#include "./ui_mainwindow.h"
#include "mainwindow.h"
MainWindow::MainWindow (QWidget *parent) :
    QMainWindow (parent),
    ui (new Ui::MainWindow) {
    ui->setupUi (this);
    tim.start ();
    connect (&timer, &QTimer::timeout, this, &MainWindow::OnTimer);
    timer.setTimerType (Qt::PreciseTimer);
    timer.setSingleShot (true);
    resize (1240, 610 + ME);
    DOU = false;
    m_game.m_wnd = this;
    Init ();
    gl = new MyGLWidget (this);
    gl->m_wnd = this;
    gl->ty = 1;
    gl->resize (1040, 610);
    gl->move (100, ME);
    gl->lower ();
    gl->show ();
    gx = new MyGLWidget (this);
    gx->m_wnd = this;
    gx->ty = 0;
    gx->resize (100, 610);
    gx->move (0, ME);
    gx->show ();
    srand (time (NULL));
#ifndef Q_OS_ANDROID //菜单栏
    connect (ui->a_open, &QAction::triggered, this, &MainWindow::on_open_clicked);
    connect (ui->a_save, &QAction::triggered, this, &MainWindow::on_save_clicked);
    connect (ui->a_buy, &QAction::triggered, this, &MainWindow::on_buy_clicked);
    connect (ui->a_quick, &QAction::triggered, this, &MainWindow::on_quick_clicked);
    connect (ui->a_start, &QAction::triggered, this, &MainWindow::on_btc_clicked);
    connect (ui->a_add, &QAction::triggered, this, &MainWindow::jiasu);
    connect (ui->a_sub, &QAction::triggered, this, &MainWindow::jiansu);
    connect (ui->a_sta, &QAction::triggered, this, &MainWindow::ViewStatus);
    connect (ui->a_quit, &QAction::triggered, this, &MainWindow::Quit);
    connect (ui->a_over, &QAction::triggered, this, &MainWindow::GameOver);
    connect (ui->a_ret, &QAction::triggered, this, &MainWindow::Retina);
    connect (ui->a_sun, &QAction::triggered, this, &MainWindow::SwitchSun);
    connect (ui->a_xue, &QAction::triggered, this, &MainWindow::ShowLife);
    connect (ui->a_swi, &QAction::triggered, this, &MainWindow::ChangeZw);
#else
    ui->menubar->setVisible (0);
#endif
    QButtonGroup *gp = new QButtonGroup (this);
    gp->addButton (ui->easy);
    gp->addButton (ui->normal);
    gp->addButton (ui->hard);
    gp->addButton (ui->tui);
    gp->addButton (ui->water);
    gp->addButton (ui->xin);
    ui->buy->setVisible (0);
    font_fam=font().family();
}
MainWindow::~MainWindow () {
    delete gl;
    delete gx;
    delete ui;
}
void MainWindow::SolveWSAD(int tx,int ty)
{
    if (tx >= 0 && tx <= (MM - 1) * SI && ty >= 0 && ty < MN && m_game.GetZwShu (tx, ty) == -1 && TM - m_game.m_ice[tx / SI][ty] >= (m_hd ? 800 : 400) && !m_game.m_dc[tx / SI][ty]) {
        int z = m_game.GetZwShu (sele_x, sele_y);
        if (z != -1) {
            m_game.plants[z].x = tx, m_game.plants[z].y = ty;
            m_game.CalZw ();
        }
        else if (m_game.m_dc[sele_x / SI][sele_y] && (sele_x != tx || sele_y != ty)) {//移动地刺
            m_game.m_dc[tx / SI][ty] = m_game.m_dc[sele_x / SI][sele_y];
            m_game.m_dc[sele_x / SI][sele_y] = 0;
        }
        sele_x = tx;
        sele_y = ty;
    }
}

void MainWindow::SolveDz (QPoint pt) //处理大招
{
    if (beans > 0) {
        int x = int ((pt.x () - 150) / SI) * SI;
        int y = int ((pt.y () - 60) / SI);
        if (pt.x () >= 150 && pt.y () >= 60 && x >= 0 && x <= (MM - 1) * SI && y >= 0 && y < MN) //位置合法
        {
            int rt = m_game.GetZwShu (x, y);
            if (rt != -1) {
                bool rtn = DaZhao (m_game.plants[rt], this);
                if (rtn) //成功
                    beans -= 1;
            }
        }
    }
}

void MainWindow::DoDraw () {
    QPainter memdc (this);
    memdc.drawPixmap (QRect (QPoint (gl->pos ().x () + gl->size ().width (), ME), MSize (330, 610)), ico[125]); //绘制背景
    if (m_game.scene == 2 || m_game.scene == 3) //夜晚变暗
    {
        memdc.setPen (Qt::NoPen);
        memdc.setBrush (QColor (0, 0, 60, 60));
        memdc.drawRect (QRect (MPoint (1140, ME), MSize (330, 610)));
    }
    if (!is11) //绘制大波僵尸的红线
    {
        QPen p (QColor (255, 0, 0));
        p.setWidth(2);
        p.setStyle (Qt::SolidLine);
        memdc.setPen (p);
        int x = ui->prog->pos ().x (), y = ui->prog->pos ().y () + ME, z = ui->prog->size ().width (), s = 0;
        for (int i = 0; i < ND - 1; i++)
            s += m_jg[i] / m_time[i];
        if (s != 0) {
            for (int i = 1, h = 0; i < ND; i++) {
                if (isdb[i])
                    memdc.drawLine (x + z * h / s, y, x + z * h / s, y - 3);
                h += m_jg[i] / m_time[i];
            }
        }
    }
    memdc.end ();
}
void MainWindow::paintEvent (QPaintEvent *event) {
    QSize s = size ();
    double a = s.width () / 1240.0;
    double b = s.height () / (ME + 610.0);
    double od = zoom;
    zoom = (a < b ? a : b);
    if (fabs (od - zoom) > 1e-10)
        Initicon ();
#ifdef Q_OS_ANDROID
    QFont f ("", floor (5 * m_sf), false);
    setFont (f);
#endif
    gl->resize (floor (1040 * zoom + 1e-10), floor (610 * zoom + 1e-10));
    gx->resize (floor (100 * zoom + 1e-10), floor (610 * zoom + 1e-10));
    gl->move (floor (100 * zoom + 1e-10), ME);
    DoDraw ();
}

void MainWindow::InitZw()
{
    QColor nul;//创建植物：子弹颜色，攻击力(负数表示特殊植物)，间隔时间，大招时间,移动速度(子弹),生命值,0,0,图片ID,阳光,类型,子弹大小,是否寒冰,是否蘑菇,是否灰烬类
    plants[0].Create (nul, -1, 14000 * pow (SI / 110.0, 0.3), 1500, 0, 80, 0, 0, 2, 50, 1); //向日葵
    plants[1].Create (QColor (0, 205, 0), 1, 1600, 8000, 4, 80, 0, 0, 1, 100, 0, 18 * SI / 110); //豌豆射手
    plants[2].Create (nul, 0, 100000000, 100000000, 0, 600, 0, 0, 4, 50, 2); //坚果
    plants[3].Create (nul, -2, 1, 0, 0, 50, 0, 0, 7, 150, 3); //炸弹
    plants[4].Create (QColor (255, 0, 0), 1, 1800, 8000, 4, 80, 0, 0, 8, 225, 4, 18 * SI / 110); //火球射手
    plants[5].Create (nul, -3, 1, 0, 0, 50, 0, 0, 9, 125, 5); //火爆辣椒
    plants[6].Create (QColor (0, 255, 255), 1, 1600, 8000, 4, 80, 0, 0, 48, 150, 9, 18 * SI / 110, true); //寒冰射手
    plants[7].Create (nul, 0, 100000000, 100000000, 0, 1600, 0, 0, 11, 125, 6); //高坚果
    plants[8].Create (nul, -4, 1, 0, 0, 100000000, 0, 0, 12, 50, 7); //倭瓜
    plants[9].Create (QColor (0, 200, 0), 3, 3000, 2500, 5, 80, 0, 0, 43, 375, 8, 30 * SI / 110); //西瓜
    plants[10].Create (nul, -8, 1000, 100000000, 0, 500, 0, 0, 82, 100, 19); //恢复坚果
    plants[12].Create (nul, -9, 7000 * pow (SI / 110.0, 0.3), 1700, 0, 80, 0, 0, 94, 150, 20); //双子
    plants[16].Create (nul, 80, 350, 0, 0, 80, 0, 0, 71, 25, 17, 40, true, false, true); //土豆地雷
    plants[41].Create(QColor (0, 203, 0),1,1600,8000,4,80,0,0,168,325,41,17 * SI / 110);//三线射手
    plants[36].Create (nul, 0, 100000000, 0, 0, 80, 0, 0, 149, 175, 36); //火炬

    plants[15].Create (nul, 0, 100000000, 0, 0, 80, 0, 0, 56, 25, 11); //灯
    plants[14].Create (nul, 80, 300, 0, 100, 80, 0, 0, 68, 150, 16, 0, false, false, true); //大嘴花
    plants[13].Create (nul, -10, 1000, 1500, 0, 80, 0, 0, 95, 125, 21); //医疗

    plants[17].Create (nul, -5, 10000 * pow (SI / 110.0, 0.3), 1700, 0, 80, 0, 0, 57, 25, 12, 0, false, true); //阳光菇
    plants[18].Create (QColor (255, 0, 255), 1, 1600, 8000, 4, 40, 0, 0, 58, 0, 13, 10 * SI / 110, false, true); //小喷菇
    plants[19].Create (nul, -6, 1, 0, 0, 20, 0, 0, 63, 175, 15, 10, false, true); //毁灭菇
    plants[20].Create (nul, -7, 1, 0, 0, 20, 0, 0, 72, 125, 18, 0, false, true); //寒冰菇
    plants[32].Create (nul, 0, 100000000, 0, 0, 3, 0, 0, 141, 100, 32, 0, 0, true); //魅惑菇
    plants[40].Create(nul,-16,500,0,0,80,0,0,158,75,40,0,0,1);//磁力菇

    plants[21].Create (nul, 0, 100000000, 0, 0, 0, 0, 0, 62, 25, 14); //荷叶
    plants[22].Create (QColor (255, 255, 0), 1, 1500, 3000, 4, 80, 0, 0, 98, 150, 22, 10 * SI / 110); //星星
    plants[23].Create (nul, -11, 1200, 2000, 0, 80, 0, 0, 101, 225, 23, 0, 0, true); //忧郁蘑菇
    plants[11].Create (QColor (10, 170, 255), 4, 3200, 1800, 4, 80, 0, 0, 55, 500, 10, 30 * SI / 110, true); //冰瓜
    plants[24].Create (nul, 0, 0, 0, 0, 0, 0, 0, 102, 125, 24); //南瓜
    plants[25].Create (nul, 0, 100000000, 0, 0, 150, 0, 0, 104, 150, 25); //反弹
    plants[26].Create (nul, -12, 800, 5000, 0, 80, 0, 0, 106, 325, 26); //双头大喷菇
    plants[27].Create (nul, -13, 80000, 0, 0, 20, 0, 0, 110, 2, 27); //大葱
    plants[28].Create (nul, 0, 0, 0, 0, 0, 0, 0, 130, 75, 28); //咖啡豆
    plants[29].Create (nul, 0, 0, 0, 0, 0, 0, 0, 132, 175, 29); //地刺

    plants[30].Create (nul, -14, 3500, 0, 0, 80, 0, 0, 134, 350, 30); //大炮2
    plants[31].Create (nul, -15, 100000000, 0, 0, 80, 0, 0, 135, 350, 31); //大炮1
    plants[33].Create (nul, 0, 100000000, 0, 0, 80, 0, 0, 142, 75, 33); //节点
    plants[34].Create (nul, 0, 100000000, 0, 0, 80, 0, 0, 143, 475, 34); //加速器
    plants[35].Create (nul, 0, 100000000, 100000000, 0, 600, 0, 0, 144, 75, 35); //有毒坚果
    plants[37].Create (QColor (0, 205, 0), 1, 1600, 2200, 4, 80, 0, 0, 155, 125, 37, 18 * SI / 110); //豌豆荚
    plants[38].Create (nul, 0, 0, 0, 0, 0, 0, 0, 157, 0, 38);//化肥
    plants[39].Create(QColor(0,0,0),1,1000,2200,4,80,0,0,159,225,39,0);//仙人掌
    plants[42].Create (nul, -17, 1, 0, 0, 50, 0, 0, 169, 250, 42); //魅惑炸弹
    plants[43].Create(nul,0,0,0,0,0,0,0,170,10,43);//翻转

    for(int i=0;i<MAXSHU;i++)plt_p[i]=10,plt_sum[i]=0;
    plt_sum[0]=-1;
    int era[20]={0,12,15,17,18,19,20,21,27,28,30,31,33,40,43};
    for(int i=0;i<20;i++)plt_p[era[i]]=0;
    plt_p[37]=15;
    plt_p[25]=plt_p[29]=7;
    plt_p[2]=plt_p[10]=plt_p[7]=plt_p[35]=4;
    plt_p[8]=plt_p[16]=plt_p[14]=3;
    plt_p[3]=plt_p[5]=2;
    plt_p[38]=plt_p[42]=1;
    plants[9].jian = plants[11].jian = 2; //溅射伤害
    plants[4].jian = 1;
    int shun[MAXSHU]={0,1,2,3,4,5,6,7,8,9,10,12,16,41,36,43,15,14,13,17,18,19,20,32,40,21,22,23,11,24,25,26,27,28,29,30,31,33,34,35,37,38,39,42};//顺序
    for(int i=0;i<MAXSHU;i++)
        m_shun[i]=shun[i];

    int zws[ZGQS] = {3, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1,1,1};
    zws[20] = zws[21]=zws[22]=2;
    zws[40] = 1;
    zws[41] = zws[42]=zws[43]=3;
    zws[50] = 3;
    zws[51] = 2;
    zws[52] = 2;
    zws[53] = 2;//每关的增量
    for (int n = 1; n < ZGQS; n++)
        zws[n] += zws[n - 1];
    for (int n = 0; n < ZGQS; n++)
        plt_cnt[n] = zws[n];
    //wsad:63关, wsad2:69关
    for (int i = 0; i < MAXSHU; i++)
        wsad[i] = wsad2[i] = 0;
    wsad2[7] = wsad2[11] = wsad2[14] = wsad2[22] = wsad2[26] = wsad2[29] = wsad2[36] = wsad2[37] = wsad2[39] = wsad2[40] = 1;
    wsad[6] = 1;wsad[7] = 2;wsad[9] = 1;wsad[10] = 2;wsad[11] = 2;
    wsad[13] = 1;wsad[14] = 2;wsad[22] = 2;wsad[23] = 2;wsad[26] = 1;
    wsad[27] = 1;wsad[34] = 1;wsad[35] = 1;wsad[36] = 1;wsad[37] = 1;
    wsad[39] = 1;wsad[41] = 1;
    //冷却速度
    cd_spd[0] = 12;cd_spd[1] = 15;cd_spd[2] = 6;cd_spd[3] = 0.9;cd_spd[4] = 12;
    cd_spd[5] = 1.1;cd_spd[6] = 12;cd_spd[7] = 5;cd_spd[8] = 2;cd_spd[9] = 10;
    cd_spd[10] = 5.5;cd_spd[11] = 3.8;cd_spd[12] = 8;cd_spd[13] = 3;cd_spd[14] = 2.5;
    cd_spd[15] = 12;cd_spd[16] = 4;cd_spd[17] = 15;cd_spd[18] = 12;cd_spd[19] = 0.7;
    cd_spd[20] = 1.8;cd_spd[21] = 12;cd_spd[22] = 7;cd_spd[23] = 7;cd_spd[24] = 6;
    cd_spd[25] = 6;cd_spd[26] = 7.5;cd_spd[27] = 5;cd_spd[28] = 8;cd_spd[29] = 4;
    cd_spd[30] = 0.9;cd_spd[31] = 0.9;cd_spd[32] = 2;cd_spd[33] = 2.5;cd_spd[34] = 1.7;
    cd_spd[35] = 4.5;cd_spd[36] = 7;cd_spd[37] = 20;cd_spd[38] = 0;cd_spd[39]=10;
    cd_spd[40] = 10;cd_spd[41]=5;cd_spd[42]=0.65;cd_spd[43]=8;
    for(int i=0;i<MAXSHU;i++)tyToNum[plants[i].type]=i;
    int Prot[12]={2,6,19,35,3,5,7,17,15,18,32,42};
    for(int i=0;i<12;i++)prot[Prot[i]]=1;
}

void MainWindow::InitJs()
{
    //创建僵尸：速度，生命，吃的速度，0，0，图片ID，编号，是否能跳跃，是否发射
    zombies[0].Create (1, 7, 1, 0, 0, 3, 0); //普通僵尸
    zombies[1].Create (1, 20, 1, 0, 0, 5, 1); //塑料僵尸
    zombies[2].Create (2, 16, 1, 0, 0, 29, 5, true); //撑杆跳僵尸
    zombies[3].Create (1, 50, 1, 0, 0, 6, 2); //铁桶僵尸
    zombies[4].Create (1, 20, 4, 0, 0, 32, 6); //大嘴僵尸
    zombies[5].Create (2, 35, 1, 0, 0, 10, 3); //跑步僵尸
    zombies[6].Create (1, 18, 1, 0, 0, 24, 4); //报纸僵尸
    zombies[7].Create (1, 75, 2, 0, 0, 36, 7); //铁门僵尸
    zombies[8].Create (1, 19, 1, 0, 0, 73, 13, false, true); //豌豆射手僵尸
    zombies[9].Create (2, 21, 1, 0, 0, 44, 8, true); //跳跳僵尸
    zombies[10].Create (1, 23, 1, 0, 0, 79, 14, false, true); //冰瓜僵尸
    zombies[11].Create (2, 80, 56, 0, 0, 65, 12); //小车僵尸
    zombies[12].Create (1, 200, 3600, 0, 0, 49, 9); //巨人僵尸
    zombies[13].Create (1, 20, 0, 0, 0, 92, 15); //苦力怕
    zombies[14].Create (2, 25, 2, 0, 0, 96, 16, false, true); //末影人
    zombies[15].Create (1, 35, 1, 0, 0, 107, 17); //张楠
    zombies[16].Create (1, 33, 1, 0, 0, 147, 18, true); //气功僵尸
    zombies[17].Create(2,15,1,0,0,160,19,true);//气球僵尸
    zombies[18].Create(1,32,4,0,0,163,20);//喷火僵尸
    for (int i = 0, j = 0; i < MAXJSH; i++) {
        zmb_sum[i]=0;
        if (i == 8 || i == 11 || (i >= 13 && i <= 15) || i == 9)
            continue;
        x_js[j++] = i;
        j_yg[i] = zombies[i].life * 5; //僵尸的阳光
        if (i == 16)
            j_yg[i] *= 3;
        else if (i == 10)
            j_yg[i] *= 3;
        if (zombies[i].eat == 4)
            j_yg[i] += 25;
        if (zombies[i].spd > 1)
            j_yg[i] += 50;
        j_yg[i] /= 1.1;
        j_yg[i] = ((j_yg[i] + 3) / 5) * 5;
    }
    for (int i = 0; i < 18; i++)
        can_wat[i] = false;
    can_wat[0] = can_wat[1] = can_wat[2] = can_wat[5] = can_wat[6] = can_wat[8] = can_wat[13] = true; //是否能下水
    //相对概率
    zmb_p[0] = 3;zmb_p[1] = 4;zmb_p[2] = 4;zmb_p[3] = 5;zmb_p[4] = 5;
    zmb_p[5] = 6;zmb_p[6] = 5;zmb_p[7] = 8;zmb_p[8] = 6;zmb_p[9] = 5;
    zmb_p[10] = 4;zmb_p[11] = 3;zmb_p[12] = 3;zmb_p[13] = 5;zmb_p[14] = 4;
    zmb_p[15] = 3;zmb_p[16] = 4;zmb_p[17] = 4;zmb_p[18] = 6;
}

void MainWindow::Init () {
    MN = 5;MM = 9;SI = 110;
    if (DOU)MN *= 2, MM *= 2, SI /= 2;//双倍
    InitZw();InitJs();
    if (SI <= 55) //双倍
    {
        for (int i = 0; i < MAXSHU; i++)
            cd_spd[i] *= 1.1, wsad[i] *= 2,wsad2[i]*=2;
    }
    m_game.m_wnd = this;
    for (int n = 0; n < MXUAN; n++)
        m_xuan[n] = -1;
    l48 = TM = SHU = JSH = ND = zf_len=sun_dou=sun_doued=0;
    m_b48 = isstop = false;
    beans=bean_use= tmr_cnt = dis_sum=stop_cnt=eat_cnt=eat_sum=dang_cnt=0;
    select = sele_x = sele_y = -1;
    timer.stop ();
    Initicon ();
    for (int i = 0; i < MN; i++)
        m_lstJ[i] = m_lstC[i] = m_lstD[i] = m_lstT[i] = m_lstB[i] = m_lstZ[i]=0;
    int ne[7] = {1, 6, 4, 26, 22, 9, 11};//2048顺序
    for (int i = 0; i < 6; i++)
        n_2048[plants[ne[i]].type] = plants[ne[i + 1]].type;
    n_2048[plants[ne[6]].type] = -1;
}
void MainWindow::Initicon () //预处理图标
{
    zoom*=b_ret;
    for (int i = 1; i <= 172; i++) {
        QImage ld (QString::asprintf ("://icons/%d.png", i));
        QImage ic(ld.width(),ld.height(),QImage::Format_ARGB32);
        for (int x = 0; x < ic.width (); x++)
        {
            for (int y = 0; y < ic.height (); y++) {
                ic.setPixelColor(x,y, ld.pixelColor (x, y));
            }
        }
        if (i >= 116 && i <= 124) {
            ico[i] = QPixmap::fromImage (ic);
            continue;
        }
        else if (i == 139 || i == 140 || i == 150)//子弹图像
            ico[i] = QPixmap::fromImage (ic.scaled (floor (ic.width () * SI / 220.0 * zoom), floor (ic.height () * SI / 220.0 * zoom), Qt::KeepAspectRatio));
        else if(i==161)//仙人掌刺
            ico[i] = QPixmap::fromImage (ic.scaled (floor (ic.width () * SI / 110.0 * zoom), floor (ic.height () * SI / 110.0 * zoom), Qt::KeepAspectRatio));
        else if (i == 115 || i == 111 || i == 113 || i == 125)//背景图像
            ico[i] = QPixmap::fromImage (ic.scaled (floor (ic.width () / 2.0 * zoom), floor (ic.height () / 2.0 * zoom), Qt::KeepAspectRatio));
        else {
            if (i == 49 || i == 51 || i == 52)//巨人
                ico[i] = QPixmap::fromImage (ic.scaled (floor (ic.width () * 1.3 / 3.0 * zoom / (DOU ? 2 : 1)), floor (ic.height () * 1.3 / 3.0 * zoom / (DOU ? 2 : 1)), Qt::KeepAspectRatio));
            else
                ico[i] = QPixmap::fromImage (ic.scaled (floor (ic.width () / 2.0 * zoom / (DOU ? 2 : 1)), floor (ic.height () / 2.0 * zoom / (DOU ? 2 : 1)), Qt::KeepAspectRatio));
            for (int x = 0; x < ic.width (); x++) //变蓝
            {
                for (int y = 0; y < ic.height (); y++) {
                    QColor rgb = ic.pixelColor (x, y);
                    int r, g, b, a;
                    rgb.getRgb (&r, &g, &b, &a);
                    if (a != 255)
                        continue;
                    r >>= 1; g >>= 1; b <<= 1;
                    if (b > 255)
                        b = 255;
                    ic.setPixelColor(x, y, QColor (r, g, b));
                }
            }
            ico_bl[i] = QPixmap::fromImage (ic);
            icm_bl[i] = QPixmap::fromImage (ic.mirrored (true, false));
            if (i == 28) {
                ico_mir[i] = ico_rd[i]=ico[i];
                continue;
            }
            ic = ico[i].toImage ();
            ico_mir[i] = QPixmap::fromImage (ic.mirrored (true, false)); //水平翻转
            ic=ic.mirrored(true,false);
            for (int x = 0; x < ic.width (); x++) //变红
            {
                for (int y = 0; y < ic.height (); y++) {
                    QColor rgb = ic.pixelColor (x, y);
                    int r, g, b, a;
                    rgb.getRgb (&r, &g, &b, &a);
                    if (a != 255)
                        continue;
                    r <<= 1; g >>= 1; b >>= 1;
                    if (r > 255)
                        r = 255;
                    ic.setPixelColor(x, y, QColor (r, g, b));
                }
            }
            ico_rd[i] = QPixmap::fromImage (ic);
        }
    }
    zoom/=b_ret;
}
bool MainWindow::AddPlant (int x, int y) {
    bool rt = false;
    if (select == -3) //大炮
    {
        m_game.m_yg += plants[3].cost;
        plants[3].x = x;
        plants[3].y = y;
        m_game.NewZw (plants[3]);
        select = -1;
        return true;
    }
    int zz;
    if ((zz = m_game.GetZwShu (x, y)) != -1 && m_game.plants[zz].type == 30 && m_game.plants[zz].tag == 10 &&select==-1) //大炮(完整), 且恢复完毕
    {
        int tz = m_game.GetZwShu (x - SI, y);
        if (tz != -1 && m_game.plants[tz].type == 31) {
            select = -3,sele_x=-1;
            m_game.plants[zz].tag = 0;
        }
    }
    if (x >= 0 && x <= (MM - 1) * SI && y >= 0 && y < MN && select != -1) {
        if ((!is11 || is12)&&!b_guan) //非滚卡
        {
            if (cd[select] > 800 - eps) {
                if(b_zhu)//柱子
                {
                    for(int s=0;s<MN;s++)
                    {
                        plants[select].x = x;
                        plants[select].y = s;
                        if (m_game.NewZw (plants[select]))
                            cd[select] = 0;
                    }
                }
                else
                {
                    plants[select].x = x;
                    plants[select].y = y;
                    if (m_game.NewZw (plants[select]))
                        cd[select] = 0;
                }
            }
            gl->update ();
            gx->update ();
        }
        else //滚卡
        {
            plants[select].x = x;
            plants[select].y = y;
            if (m_game.NewZw (plants[select])) {
                int n = 0;
                for (n = 0; n < SHU; n++) {
                    if (m_xuan[n] == select)
                        break;
                }
                for (n += 1; n < SHU; n++)
                    m_xuan[n - 1] = m_xuan[n];
                SHU -= 1;
                m_xuan[SHU] = -1;
                m_game.m_yg = 9999;
            }
        }
        rt = true;
    }
    if (rt && select != -3)
        select = -1;
    return rt;
}
bool MainWindow::AddPlant (QPoint pt) {
    return AddPlant (((pt.x () - 150) / SI) * SI, (pt.y () - 60) / SI);
}
bool MainWindow::AddJs (QPoint pt) //手动添加僵尸
{
    if (select < 0)
        return false;
    int x = ((pt.x () - 150) / SI) * SI, y = (pt.y () - 60) / SI;
    if (x >= MN * SI && x <= MM * SI && y >= 0 && y < MN && m_game.m_yg >= j_yg[select]) {
        m_game.m_yg -= j_yg[select];
        zombies[select].x = x;
        zombies[select].y = y;
        m_game.NewJs (zombies[select]);
        select = -1;
        return true;
    }
    return false;
}

//计算几何开始
struct SPt {
    int x, y;
    SPt () {
    }
    SPt (int X, int Y) {
        x = X;
        y = Y;
    }
};
typedef SPt SVe;
SPt operator+ (const SPt &a, const SVe &b) {
    return SPt (a.x + b.x, a.y + b.y);
}
SVe operator- (const SPt &a, const SPt &b) {
    return SVe (a.x - b.x, a.y - b.y);
}
int operator* (const SVe &a, const SVe &b) {
    return a.x * b.y - a.y * b.x;
}
SVe operator* (const SVe &a, double b) {
    return SVe (int (a.x * b + 0.5), int (a.y * b + 0.5));
}
SPt jiaod (const SPt &a, const SVe &va, const SPt &b, const SVe &vb) {
    double t = double ((b - a) * vb) / (va * vb);
    return a + va * t;
}
bool inside (const SPt &a, const SPt &b, const SPt &c) {
    if ((c.x < a.x || c.x > b.x) && (c.x < b.x || c.x > a.x))
        return false;
    if ((c.y < a.y || c.y > b.y) && (c.y < b.y || c.y > a.y))
        return false;
    return true;
}
bool check (const SPt &a, const SPt &b, const SPt &c, const SPt &d) {
    if ((b - a) * (d - c) == 0)
        return false;
    SPt z = jiaod (a, b - a, c, d - c);
    return inside (a, b, z) && inside (c, d, z);
}
bool jiaorect (int x, int y, const SPt &a, const SPt &b) {
    SPt z0 (x + SI / 4, y + SI / 6), z1 (x + SI * 3 / 4, y + SI / 6), z2 (x + SI * 3 / 4, y + SI * 5 / 6), z3 (x + SI / 4, y + SI * 5 / 6);
    return check (z0, z1, a, b) || check (z1, z2, a, b) || check (z2, z3, a, b) || check (z3, z0, a, b);
}
//计算几何结束

void MainWindow::GenerateJs()
{
    /*int r = rand () % m_p[m_nd], n = 0; //m_nd:当前的僵尸种类数
    for (n = 0; n < JSH; n++) {
        if (r < m_p[n])
            break;
    } //随机生成一种(加权)*/
    int n=MyRand(zmb_sum,zmb_p,m_nd+1);
    zmb_sum[n]+=1;
    zombies[n].x = (MM - 1) * SI + SI / 2;
    if (n == 10) //冰瓜僵尸：寻找掩护
    {
        int maxs = -100, wz;
        if (m_hbzw) {
            for (int j = 0; j < MN; j++) {
                int shu = (tm - m_lstB[j]) - (tm - m_lstC[j]); //小车
                if (shu > maxs) {
                    maxs = shu;
                    wz = j;
                }
            }
        }
        if (maxs == -100) {
            for (int j = 0; j < MN; j++) {
                int shu = (tm - m_lstB[j]) - (tm - m_lstJ[j]); //巨人
                if (shu > maxs) {
                    maxs = shu;
                    wz = j;
                }
            }
            if (maxs == -100) {
                for (int j = 0; j < MN; j++) {
                    int shu = (tm - m_lstB[j]) - (tm - m_lstD[j]); //盾牌
                    if (shu > maxs) {
                        maxs = shu;
                        wz = j;
                    }
                }
                if (maxs == -100) {
                    for (int j = 0; j < MN; j++) {
                        int shu = (tm - m_lstB[j]) - (tm - m_lstT[j]); //铁桶
                        if (shu > maxs) {
                            maxs = shu;
                            wz = j;
                        }
                    }
                    if (maxs == -100)
                        wz = rand () % MN;
                }
            }
        }
        zombies[n].y = wz;
        m_lstB[wz] = tm;
    }
    else if (n == 8 || n == 4) //大嘴，豌豆射手：寻找掩护
    {
        int maxs = 200, wz; //8秒
        for (int j = 0; j < MN; j++) {
            int shu = tm - m_lstC[j]; //小车
            if (shu < maxs) {
                maxs = shu;
                wz = j;
            }
        }
        if (maxs == 200) {
            for (int j = 0; j < MN; j++) {
                int shu = tm - m_lstJ[j]; //巨人
                if (shu < maxs) {
                    maxs = shu;
                    wz = j;
                }
            }
            if (maxs == 200) {
                for (int j = 0; j < MN; j++) {
                    int shu = tm - m_lstD[j]; //盾牌
                    if (shu < maxs) {
                        maxs = shu;
                        wz = j;
                    }
                }
                if (maxs == 200) {
                    for (int j = 0; j < MN; j++) {
                        int shu = tm - m_lstT[j]; //铁桶
                        if (shu < maxs) {
                            maxs = shu;
                            wz = j;
                        }
                    }
                    if (maxs == 200)
                        wz = rand () % MN;
                }
            }
        }
        zombies[n].y = wz;
    }
    else if (n == 12) //巨人：防止生成在一行
    {
        int max = -1, wz;
        for (int j = 0; j < MN; j++) {
            int shu = tm - m_lstJ[j];
            if (shu > max) {
                max = shu;
                wz = j;
            }
        }
        zombies[n].y = wz;
        m_lstJ[wz] = tm;
    }
    else if (n == 11) //小车：防止生成在一行
    {
        int max = -1, wz;
        for (int j = 0; j < MN; j++) {
            int shu = tm - m_lstC[j];
            if (shu > max) {
                max = shu;
                wz = j;
            }
        }
        zombies[n].y = wz;
        m_lstC[wz] = tm;
    }
    else if (n == 7) //盾牌：防止生成在一行
    {
        int max = -1, wz;
        for (int j = 0; j < MN; j++) {
            int shu = tm - m_lstD[j];
            if (shu > max) {
                max = shu;
                wz = j;
            }
        }
        zombies[n].y = wz;
        m_lstD[wz] = tm;
    }
    else if (n == 3 || n==5) //铁桶：防止生成在一行
    {
        int max = -1, wz;
        for (int j = 0; j < MN; j++) {
            int shu = tm - m_lstT[j];
            if (shu > max) {
                max = shu;
                wz = j;
            }
        }
        zombies[n].y = wz;
        m_lstT[wz] = tm;
    }
    else {
        if (m_game.wat_cnt && can_wat[zombies[n].type] && rand () % 2 == 0 && jd > 100) //后期增大水池概率
            zombies[n].y = m_game.wat_row[rand () % m_game.wat_cnt];
        else
        {
            int m_kx[MMN],ss=0;
            for(int i=0;i<MN;i++)
            {
                if(tm-m_lstZ[i]>25)
                    m_kx[ss++]=i;
            }
            if(ss==0)
                zombies[n].y = rand () % MN;
            else
                zombies[n].y=m_kx[rand()%ss];//尽量均匀分布
        }
    }
    Zombie js = zombies[n];
    m_lstZ[js.y]=tm;
    if (f_shu && js.type == 7) //化肥僵尸
    {
        js.fei = true;
        f_shu -= 1;
        js.spd *= 2;
        js.life *= 1.5;
        js.eat *= 1.5;
    }
    if(b_zhu)//柱子
    {
        for(int s=0;s<MN;s++)
        {
            js.y=s;
            m_game.NewJs(js);
        }
    }
    else m_game.NewJs (js);
    if (mirr) //镜面关卡
    {
        js.x = -100;
        js.spd = -js.spd;
        m_game.NewJs (js);
    }
    if (!is11) //普通关卡
    {
        jd += 1;
        ui->prog->setValue (jd);
        ui->prog->update();
        if (jd % 50 == 0)
            f_shu += 1; //增加化肥
    }
}

void MainWindow::ChangeZw()
{
    bool bk = false;
    if (!isstop)
        on_stop_clicked (), bk = true;
    Choose *ch = new Choose (this);
#ifdef Q_OS_ANDROID
    QFont f ("", floor (8 * m_sf), false);
    ch->setFont (f);
#endif
    ch->SHU = SHU;
    ch->XUAN = XUAN;
    ch->JSH = JSH;
    ch->setWindowTitle ("更换植物");
    for (int i = 0; i < SHU; i++) {
        ch->yg[i] = plants[i].cost;
        ch->ico[i].load (QString::asprintf ("://icons/%d.png", plants[i].id));
    }
    for (int i = 0; i < JSH; i++)
        ch->icj[i].load (QString::asprintf ("://icons/%d.png", zombies[i].id));
    ch->setWindowModality (Qt::ApplicationModal);
    ch->Init ();
    ch->show ();
    if (ch->exec ()) {
        for (int i = 0; i < XUAN; i++)
            m_xuan[i] = ch->xuan[i];
        m_hbzw = false;
        for (int n = 0; n < XUAN; n++) {
            if (plants[m_xuan[n]].freeze)
                m_hbzw = true;
        }
    }
    if (bk)
        on_stop_clicked ();
}

void MainWindow::NextBo()
{
    KillTimer (1002);
    int lj = m_jg[m_n];
    m_n += 1; //下一波
    if (m_n > ND - 1)
        m_n = ND - 1;
    SetTimer (1002, m_time[m_n], NULL); //重置生成速度
    KillTimer (1004);
    SetTimer (1004, m_jg[m_n], NULL); //重置修改速度
    if (lj != 1) //并非前期的几个僵尸
    {
        bool sho = false;
        if (ui->Short->isChecked ())
            sho = true;
        //增加僵尸种类
        int od=m_nd;
        if (sho && !m_game.endless) {
            if ((m_gq % 10 == 0 || m_gq == MAXGQS + 3) && r_gq != MAXGQS + 5)
                m_nd += 1 + (m_n % 2 == 0);
            else
                m_nd += 1 + (m_n % 4 == 0);
        }
        else {
            if (m_game.endless) //64关放慢速度
                m_nd += (m_n % 2 != 0);
            else if ((m_gq % 10 == 0 || m_gq == MAXGQS + 3) && r_gq != MAXGQS + 5)
                m_nd += 1;
            else
                m_nd += (m_n % 3 != 0);
        }
        if (m_nd > JSH - 1) //上限
            m_nd = JSH - 1;
        if(m_nd>od)
        {
            for(int i=0;i<MAXJSH;i++)
                zmb_sum[i]=0;
        }
    }
    if (ND == 90 && m_n >= 40 && m_n % 5 == 0) //增加难度(等差等比)
    {
        for (int i = 0; i < MAXJSH; i++) //增加血量
            zombies[i].life += 7;
        if (m_n % 10 == 0) {
            for (int i = 10; i <= 12; i++) {//增大巨人小车射手概率
                //for (int j = i; j < MAXJSH; j++)
                    zmb_p[i] += 1;
            }
            for (int i = 0; i < MAXJSH; i++) {
                if (i != 11 && i % 2 == (m_n / 10) % 2)
                    zombies[i].spd += 1;//加速
                if (zombies[i].spd > 5)//上限
                    zombies[i].spd = 5;
                if (zombies[i].eat != 40) {
                    if (zombies[i].eat == 1)
                        zombies[i].eat *= 2;
                    else
                        zombies[i].eat *= 1.5;
                }
            }
            m_game.m_yg /= 1.5;
        }
        if (m_n % 15 == 0) { //减慢恢复
            for (int i = 0; i < MAXSHU; i++)
                cd_spd[i] *= 0.9;
        }
    }
    if (isdb[m_n]) //一大波僵尸
    {
        Zombie js;
        js.Create (3, m_gq <= 6 ? 10 : 20, 1, (MM - 1) * SI + 5, MN / 2, 40, -1); //旗帜僵尸
        m_game.NewJs (js);
        if (mirr) {
            js.x = -100;
            js.spd = -js.spd;
            m_game.NewJs (js);
        }
    }
}

void MainWindow::WanQuanTu()
{
    for (int i = 0; i < m_game.plt_cnt; i++) {
        if (m_game.plants[i].type == 33) {
            int x1 = m_game.plants[i].x + SI / 2, y1 = m_game.plants[i].y * SI + SI / 2;
            for (int j = i + 1; j < m_game.plt_cnt; j++) {
                if (m_game.plants[j].type == 33) {
                    int x2 = m_game.plants[j].x + SI / 2, y2 = m_game.plants[j].y * SI + SI / 2;
                    for (int s = 0; s < m_game.zmb_cnt; s++) {
                        if (m_game.zombies[s].type >= 100 || !jiaorect (m_game.zombies[s].x, m_game.zombies[s].y * SI, SPt (x1, y1), SPt (x2, y2)))
                            continue;
                        m_game.zombies[s].freeze = 100;
                        m_game.zombies[s].life -= 1;
                        if (m_game.zombies[s].life <= 0) {
                            m_game.DestroyJs (s);
                            s -= 1;
                        }
                        else
                            m_game.zombies[s].id = GetJsIcon (m_game.zombies[s], m_game);
                    }
                }
            }
        }
    }
}
int MainWindow::CalScore(QString &str)
{
    if (chui)
        return (y_sum / (jd * SI / 3.0)) * 1000000;
    int x=jd,s1=0,s3=bean_use;long long s2=dis_sum;
    for (int i = 0; i < m_game.plt_cnt; i++)
        s1 += m_game.plants[i].cost;
    double a=x,b=min(s1/(MN*MM*200.0),1.0)*(x/2.0);
    int t=(MM - 1) * SI + SI / 2;
    double c=max(s2-1.0*t*t*x/2,0.0)/(1.0*t*t/2)*2,d=max(1-s3/20.0,0.0)*(x/2.0);
    int cars=0;
    for (int y = 0; y < MN; y++)
        if (m_game.car[y])cars+=1;
    double e=double(cars)/MN*x*2.4;
    double f=max(1-stop_cnt/1000.0,0.0)*x*0.6;
    double g=(eat_sum==0?1:double(eat_sum-eat_cnt)/eat_sum)*1.5*x;
    double h=(1-min(dang_cnt*10.0/x,1.0))*1.5*x;
    double sc=a+b+c+d+e+f+g+h;
    double rat=sc/(9.3*x);
    double z[5]={0,1,0.8,0.5,0.3},nd=z[m_ea];
    if(m_hd)nd=1.2;
    if(m_tui)nd=1.5;
    if(sun_doued)nd/=2;
    sc*=nd;
    str=QString::asprintf("得分细则：\n击杀%.3lf 保留%.3lf 杀速%.3lf\n能量豆%.3lf 车%.3lf 暂停%.3lf\n损伤%.3lf 危机%.3lf\n得分率：%.6lf%%\n难度加成%.2lf",a,b,c,d,e,f,g,h,rat*100,nd);
    return int(sc*100+0.5);
}

bool MainWindow::DoTimer (int nIDEvent) {
    bool rt = false;
    if (m_game.over) {
        GameOver ();
        return true;
    }
    else if (nIDEvent < 1000) //处理植物的计数器
    {
        if(!m_game.freeze_all||r_gq!=MAXGQS+13)
            rt = m_game.Goj (nIDEvent);
    }
    else {
        if (nIDEvent == 1000) //移动僵尸
        {
            for (int i = 0; i < m_game.zmb_cnt; i++) {
                if (!m_game.freeze_all || m_game.zombies[i].type >= 100 || (m_game.zombies[i].type == 12&&r_gq!=MAXGQS+13)) {
                    if (m_game.MoveJs (i))
                        i -= 1;
                }
            }
            for (int n = 0; n < MAXSHU; n++) //冷却
            {
                cd[n] += cd_spd[n];
                if (cd[n] > 800)
                    cd[n] = 800;
            }
            tm += 1; //计时器，1次0.04秒
            if (z_fs && fabs (cd[38]) < eps) //化肥数目
            {
                z_fs -= 1;
                cd[38] = 800;
            }
        }
        else if (nIDEvent == 1001) //移动子弹
        {
            m_game.MoveAllZd ();
            if (tim.elapsed () - lst_draw >= 17 || b_fast) //防止大量刷屏
            {
                gl->update ();
                gx->update ();
            }
        }
        else if (nIDEvent == 1002) //产生僵尸
        {
            if(arc)
            {
                Zombie js;
                if(arc_ty[arc_i]==-1)
                    js.Create(1,3,1,0,0,50,10);
                else js=zombies[arc_ty[arc_i]];
                js.x=(MM-1)*SI+5;js.y=arc_wz[arc_i];
                KillTimer(1002);
                SetTimer(1002,arc_tm[arc_i+1]-arc_tm[arc_i],NULL);
                m_game.NewJs(js);arc_i+=1;
                return false;
            }
            if (b_rd)
                return false;
            if (is11) //Boss关卡
            {
                int n=MyRand(zmb_sum,zmb_p,m_nd+1);
                zombies[n].x = (MM - 1) * SI + 5;
                zombies[n].y = rand () % MN;
                if (m_jwbs[zombies[n].y] > 0) //有僵王博士
                    m_game.NewJs (zombies[n]);
                return rt;
            }
            if (m_n == ND - 1) //结束
            {
                if (m_game.zmb_cnt == 0) {
                    QString str;
                    int sc=CalScore(str);
                    KillTimer (1002);
                    rt = true;
                    m_game.over = true;
                    m_game.KillAll ();
                    GameOver ();
                    str=QString::asprintf ("胜利！ 得分:%d\n", sc)+str;
                    QMessageBox::information (this, tr ("提示"), str);
                }
                return rt;
            }
            GenerateJs();
        }
        else if (nIDEvent == 1003) //白天阳光
            m_game.m_yg += (sun_dou?50:25);
        else if (nIDEvent == 1004) //生成下一波僵尸
        {
            rt = true;
            if (is11) //BOSS关卡
            {
                KillTimer (1002);
                SetTimer (1002, 900 * pow (SI / 110.0, 0.9), NULL);
                KillTimer (1004);
                return rt;
            }
            NextBo();
        }
        else if (nIDEvent == 1005) //产生植物(滚卡)
        {
            if (!is12 && SHU < XUAN) {
                int r;
                if(TM<=1000)
                {
                    int gj[8] = {1, 4, 6, 9, 11, 26, 37, 41};
                    r=gj[(plt_sum[1]++)%8];
                }
                else
                {
                    /*while (1) {
                        r = rand () % (MAXSHU - 1) + 1;
                        if ((r == 2 || r == 7 || r == 10 || r == 25) && rand () % 2 == 0)
                            continue; //不能出现
                        if ((plants[r].type == 3 || plants[r].type == 5 || plants[r].type == 16 || plants[r].type == 27 || plants[r].type == 30 || plants[r].type == 31|| plants[r].type == 42) && rand () % 5 < 3)
                            continue; //减小炸弹,坚果概率
                        if (!plants[r].mush && plants[r].type != 14 && plants[r].type != 11 && plants[r].type != 12 && plants[r].type != 20 && plants[r].type != 21 && plants[r].type != 28)
                            break;
                    }*/
                    if(plt_sum[0]==-1)plt_sum[0]=plt_sum[1]=0;
                    r=MyRand(plt_sum,plt_p,MAXSHU);
                }
                m_xuan[SHU] = r;
                SHU += 1;
            }
            for (int n = 0; n < MN; n++)
                m_jwbs[n] = 0;
            int jwz[MMN]; //BOSS的位置
            for (int n = 0; n < MN; n++)
                jwz[n] = -1;
            for (int i = 0; i < m_game.zmb_cnt; i++) {
                if (m_game.zombies[i].type == 11) {
                    m_jwbs[m_game.zombies[i].y] = m_game.zombies[i].life;
                    jwz[m_game.zombies[i].y] = i;
                }
            }
            jd = 0;
            for (int n = 0; n < MN; n++)
                jd += (SI <= 55 && is12 ? 3000 : 1000) - m_jwbs[n]; //计算BOSS血量
            ui->prog->setValue (jd);
            if (jd == MN * (SI <= 55 && is12 ? 3000 : 1000)) {
                KillTimer (1002);
                m_game.over = true;
                m_game.KillAll ();
                GameOver ();
                QMessageBox::information (this, tr ("提示"), tr ("胜利"));
            }
            for (int y = 0; y < MN; y++) {
                if (jwz[y] == -1)
                    continue;
                int z = jwz[y];
                if (m_game.zombies[z].x > (MM - 1) * SI + 5) //走出场地
                {
                    m_game.zombies[z].x = (MM - 1) * SI + 5;
                    m_game.zombies[z].spd = 0;
                }
            }
        }
        else if (nIDEvent == 1006) //取消整体寒冰
        {
            KillTimer (1006);
            rt = true;
            m_game.freeze_all = false;
        }
        else if (nIDEvent == 1007) //踩
        {
            int ma[MMN] = {0}, max = -1, may = -1;
            for (int n = 0, i = 0; n < m_game.plt_cnt; i++) {
                if (m_game.plants[i].life == -1)
                    continue;
                n += 1;
                ma[m_game.plants[i].y] += m_game.plants[i].cost;
            }
            for (int n = 0; n < MN; n++)
                m_jwbs[n] = 0;
            int jwz[MMN];
            for (int n = 0; n < MN; n++)
                jwz[n] = -1;
            for (int i = 0; i < m_game.zmb_cnt; i++) {
                if (m_game.zombies[i].type == 11) {
                    m_jwbs[m_game.zombies[i].y] = m_game.zombies[i].life;
                    jwz[m_game.zombies[i].y] = i;
                }
            }
            for (int y = 0; y < MN; y++) {
                if (m_jwbs[y] <= 0)
                    continue;
                if (ma[y] > max) //贪心
                {
                    max = ma[y];
                    may = y;
                }
            }
            if (may != -1) {
                m_game.zombies[jwz[may]].spd = 10;
                m_game.KillJsLine (may, 300); //把僵尸踩死
            }
        }
        else if (nIDEvent == 1008) //AI
            m_game.AI ();
        else if (nIDEvent == 1009) //总体计时器
        {
            for (int i = 0; i < m_game.plt_cnt; i++)
                m_game.plants[i].id = GetZwIcon (m_game.plants[i]);
            TM += 1;
            if (TM % 40 == 0) //每秒一次
            {
                WanQuanTu();//完全图伤害
                if(b_guan&&m_game.zmb_cnt==0)//砸罐胜利
                {
                    int gs=0,cn=0;
                    for(int i=0;i<m_game.plt_cnt;i++)
                    {
                        if(m_game.plants[i].type==-1)
                        {
                            gs=1;
                            break;
                        }
                    }
                    if(!gs)
                    {
                        if(!wait)
                        {
                            wait=1;m_n+=1;
                            for(int i=0;i<MN;i++)keep[1][i]=1;
                        }
                        for(int i=0;i<MN;i++)
                            for(int j=0;j<MM;j++)cn+=keep[j][i];
                        if(cn==12)MakeGuan();
                    }
                }
            }
        }
        else if (nIDEvent == 1010) //加速回复倒计时
        {
            for (int i = 0; i < XUAN; i++) {
                int t = plants[m_xuan[i]].type;
                if (t != 3 && t != 5 && t != 7 && t != 16 && t != 30 && t != 31)
                    cd_spd[m_xuan[i]] /= 10000;
            }
            KillTimer (1010);
            rt = true;
        }
        else if (nIDEvent == 1011) //回放/存档
        {
            if (!b_hui)
                return false;
            if (b_rd) //回放
            {
                HuiFang (0);
                if (w_tm == 1)
                    Initicon ();
                w_tm += (abs (h_sd) == 4 ? h_sd / 4 : h_sd);
            }
            else //存档
            {
                QString na = ui->luj->text ();
                na += QString::asprintf ("/%d.in", w_tm);
                QFile file (na);
                on_stop_clicked ();
                file.open (QIODevice::WriteOnly);
                QDataStream ar (&file);
                Save (ar);
                file.close ();
                on_stop_clicked ();
                stop_cnt-=2;
                w_tm += 1;
            }
            ui->dfn->setText (QString::asprintf ("%d", w_tm));
        }
        else //结束大招
        {
            KillTimer (nIDEvent);
            rt = true;
            QxDaZhao (m_game.plants[nIDEvent - 10000], this);
        }
    }
    return rt;
}
void MainWindow::HuiFang (bool hs) {
    QString na = ui->luj->text ();
    na += QString::asprintf ("/%d.in", w_tm);
    QFile file (na);
    m_game.started = false;
    file.open (QIODevice::ReadOnly);
    QDataStream ar (&file);
    Load (ar);file.close ();
    DOU = (SI <= 55);
    for (int i = 0; i < MN; i++)
        m_game.row_zmb[i] = 0;
    for (int i = 0; i < m_game.zmb_cnt; i++) {
        m_game.row_zmb[m_game.zombies[i].y] += 1;
        m_game.zombies[i].num = i;
    }
    for (int i = 0; i < m_game.plt_cnt; i++)
        m_game.plants[i].num = i;
    m_game.CalZw ();
    m_game.SZZ = m_game.over =false;
    m_game.m_wnd = this;
    int tt = -ui->lineEdit->text ().toInt ();
    if (tt != 0)h_sd = tt;
    else tt = h_sd;
    if (tt < 0)tt = -tt;
    if (hs) tt = 1;
    double sd = ui->speed->text ().toDouble () * tt;
    for (int i = 0; i < tmr_cnt; i++) {
        if ((tmr[i].id != 1001 || sd > 1) && tmr[i].id != 1011) {
            tmr[i].nxt /= sd;
            double tj = tmr[i].time / sd;
            if (h_sd < 0)
                tj = 1e8;
            tmr[i].time = floor (tj);
            tmr[i].extra = tj - tmr[i].time;
        }
        if (tmr[i].id == 1011 && tt == 4) {
            tmr[i].nxt /= sd;
            double tj = tmr[i].time / sd;
            tmr[i].time = floor (tj);
            tmr[i].extra = tj - tmr[i].time;
        }
        tmr[i].nxt += tim.elapsed ();
    }
    int ms = -1;
    ResetTimer ();
    for (int n = 0; n < ND - 1; n++)
        ms += int (m_jg[n] / m_time[n]);
    if (ms == -1)
        ms = 1;
    if (is11)
        ui->prog->setRange (0, MN * (SI <= 55 ? 3000 : 1000));
    else
        ui->prog->setRange (0, ms);
    ui->prog->setValue (jd);
    ui->Auto->setChecked (m_ai);
    ui->Doub->setChecked (DOU);
    ui->buy->setVisible (1);
    DisableButton();
    m_game.started = true;
    ShowButton ();
}
void MainWindow::OnTimer () {
    int nIDEvent = nxt_tmr, z = -1;
    for (int i = 0; i < tmr_cnt; i++) {
        if (tmr[i].id == nIDEvent) {
            z = i;
            break;
        }
    }
    if (z != -1) {
        v_tm=tmr[z].nxt;
        if (nIDEvent < 1000) {
            int ne[4][2] = {SI, 0, 0, 1, -SI, 0, 0, -1};
            bool zd = false;
            for (int s = 0; s < 4; s++) //寻找加速器
            {
                int x = m_game.plants[nIDEvent].x + ne[s][0], y = m_game.plants[nIDEvent].y + ne[s][1];
                if (x >= 0 && x <= (MM - 1) * SI && y >= 0 && y < MN) {
                    int t = m_game.GetZwShu (x, y);
                    if (t != -1 && m_game.plants[t].type == 34) {
                        zd = true;
                        break;
                    }
                }
            }
            if (zd) //加速器
                tmr[z].nxt += tmr[z].time * 3 / 5;
            else
                tmr[z].nxt += tmr[z].time;
        }
        else
            tmr[z].nxt += tmr[z].time;
        if (rand () % int (1e9) < floor (tmr[z].extra * 1e9)) //解决计时器的小数部分
            tmr[z].nxt += 1;
    }
    else if (nIDEvent != 700 && nIDEvent != 640)//DEBUG
        QMessageBox::warning (this, tr (""), tr ("Timer Bug"));
    DoTimer (nIDEvent);
    if (!isstop && !b_fast)
        ResetTimer ();
}

void MainWindow::SolveNd()
{
    m_ea = 1;
    if (ui->xin->isChecked ()) //新手
    {
        m_ea = 4;
        for (int i = 0; i < MAXSHU; i++) {
            plants[i].life *= 1.5;
            plants[i].time /= 1.4;
            cd_spd[i] *= 1.5;
            plants[i].cost -= 10;
            if (plants[i].cost < 0)
                plants[i].cost = 0;
        }
        for (int i = 0; i < MAXJSH; i++)
            zombies[i].life /= 1.4;
        zmb_p[10] -= 1;
        zmb_p[11] -= 1;
        zmb_p[12] -= 1;
    }
    else if (ui->water->isChecked ()) //简单
    {
        m_ea = 3;
        for (int i = 0; i < MAXSHU; i++) {
            plants[i].life *= 1.3;
            plants[i].time /= 1.25;
            cd_spd[i] *= 1.3;
            plants[i].cost -= 5;
            if (plants[i].cost < 0)
                plants[i].cost = 0;
        }
        for (int i = 0; i < MAXJSH; i++)
            zombies[i].life /= 1.25;
        zmb_p[11] -= 1;
        zmb_p[12] -= 1;
    }
    else if (ui->easy->isChecked ()) //普通
    {
        m_ea = 2;
        for (int i = 0; i < MAXSHU; i++) {
            plants[i].life *= 1.1;
            plants[i].time /= 1.1;
            cd_spd[i] *= 1.1;
            plants[i].cost -= 2;
            if (plants[i].cost < 0)
                plants[i].cost = 0;
        }
        for (int i = 0; i < MAXJSH; i++)
            zombies[i].life /= 1.1;
        zmb_p[11] -= 1;
    }
    else if (ui->normal->isChecked ()) //困难
        m_ea = 1;
    else if (ui->hard->isChecked ()) //疯狂
    {
        m_hd = true;
        for (int i = 0; i < MAXSHU; i++) {
            plants[i].life /= 1.1;
            if (plants[i].life < 1)
                plants[i].life = 1;
            plants[i].time *= 1.1;
            cd_spd[i] *= 0.93;
            if (i > 0)
                plants[i].cost += 2;
        }
        for (int i = 0; i < MAXJSH; i++) {
            zombies[i].life *= 1.2;
            if(i>=3)zombies[i].eat += 1;
        }
        zmb_p[10] += 1;
        zmb_p[11] += 1;
    }
    else if (ui->tui->isChecked ()) //不可能
    {
        m_hd = true;
        m_tui = true;
        for (int i = 0; i < MAXSHU; i++) {
            plants[i].life /= 1.25;
            if (plants[i].life < 1)
                plants[i].life = 1;
            plants[i].time *= 1.2;
            cd_spd[i] *= 0.85;
            if (i > 0)
                plants[i].cost += 5;
        }
        for (int i = 0; i < MAXJSH; i++) {
            zombies[i].life *= 1.3;
            if(i>=2)zombies[i].eat += 1;
            if(zombies[i].spd>1)zombies[i].spd += 1;
        }
        zmb_p[10] += 1;
        zmb_p[11] += 1;
        zmb_p[12] += 1;
    }
}

void MainWindow::MakeBo(bool sho,int lx,int gq,int gq2)
{
    ND = 5 + int (DBS * (gq - 1 + (lx == 5 ? 1 : 0) + (SI <= 55 ? 3 : 0)) * (sho ? 5 : 6) + 0.5) + (sho ? 5 : 6);
    m_jg[1] = m_jg[2] = m_jg[3] = 1;
    m_time[1] = m_time[2] = m_time[3] = 1e9;
    if (gq <= 8 && gq2 != MAXGQS + 9)
        m_time[0] = 17000, m_jg[0] = 35000;
    else //第一次生成多个
    {
        if(gq2 == MAXGQS + 3||gq2 == MAXGQS + 5||gq2 == MAXGQS + 9)
            m_time[0] = 3000, m_jg[0] = 4000;
        else
            m_time[0] = 13000, m_jg[0] = 14000;
        if(gq==10||gq2==MAXGQS+9)//第10关或wsad
        {
            m_time[1]=100;m_jg[1]=480;
            m_time[2]=7000;m_jg[2]=(lx==5?40000:30000);
            m_time[3]=200;m_jg[3]=1100;
        }
        else
        {
            m_time[1] = 100, m_jg[1] = 280;
            m_time[2] = 4000;m_jg[2] = 13000;
            m_time[3] = 4000;m_jg[3] = 13000;
        }
    }
    if (gq <= 8)
        m_time[4] = 10000/2;
    else if (gq == 9)
        m_time[4] = 8000/2;
    else
        m_time[4] = 7000;
    m_jg[4] = 30000;
    double dad = 2010.0 / (GQS - 1.0); //每关差值
    int dbs = 2700 - int (dad * (gq - 1) + 0.5) - (lx == 5 ? 120 : 0);
    int dbt = (sho ? 2900 : 3900) + (gq - 1) * (sho ? 250 : 480) + (lx == 5 ? 600 : 0);
    if (gq2 <= MAXGQS + 3 || gq2 == 2048 || gq2 == MAXGQS + 5 || (gq2 >= MAXGQS + 7 && gq2<=MAXGQS+10)||gq2 == MAXGQS + 14) //常规
    {
        for(int i=0;i<=ND;i++)isdb[i]=false;
        if (gq2 == 2048)
            m_b48 = true;
        for (int n = 5; n < ND; n += (sho ? 5 : 6)) {
            int i = 0, j = 0;isdb[n]=true;
            for (i = n, j = 0; i < ND - 1 && j < (sho ? 4 : 5); i++, j++)
                m_time[i] = dbs + j * (sho ? 200 : 300), m_jg[i] = dbt;
            if (sho)
                m_time[i] = 3100, m_jg[i] = 10000;
            else
                m_time[i] = 3500, m_jg[i] = 14500;
            //间歇
            dbt += (sho ? 800 : 1900);
        }
    }
    else if(b_ycl)//预处理
    {
        ND = 40;for(int i=0;i<=ND;i++)isdb[i]=false;
        int tm = 1000;
        dbt = 3000;
        int i = 0, j = 0;
        for (int n = 0; n < ND; n += 4) {
            isdb[n]=true;
            for (i = n, j = 0; i < ND && j < 4; i++, j++)
                m_time[i] = tm + j * 300, m_jg[i] = dbt;
            dbt += 800;
            tm -= 200;
            if (tm < 300)
                tm = 300;
        }
        plants[0].cost=plants[12].cost=plants[17].cost=99999;
        if(r_gq==MAXGQS+13)plants[3].cost=plants[8].cost=plants[16].cost=plants[19].cost=plants[20].cost=plants[5].cost=99999;
    }
    else //无尽
    {
        ND = 90;for(int i=0;i<=ND;i++)isdb[i]=false;
        int tm = 1170;
        dbt = 5000;
        int i = 0, j = 0;
        for (int n = 5; n < ND; n += 4) {
            isdb[n]=true;
            for (i = n, j = 0; i < ND - 1 && j < 3; i++, j++)
                m_time[i] = tm + j * 400, m_jg[i] = dbt;
            m_time[i] = 2000, m_jg[i] = 12000;
            if (i >= 45)
                m_jg[i] += 10000;
            if (i >= 60)
                m_jg[i] *= 2;
            dbt += 1000;
            tm -= 170;
            if (tm < 220)
                tm = 220;
        }
    }
}

int MainWindow::MakeGq (int gq) //制作关卡
{
    bool sho = false;
    if (ui->Short->isChecked ()) //短时
    {
        sho = true;
        double sd = ui->speed->value ();
        if (gq != MAXGQS + 6 && gq != MAXGQS + 4 && gq!=MAXGQS+11&&sd < 1.1 - 1e-10)
            sd = 1.1;
        ui->speed->setValue (sd);
    }
    chui = imjs = m_tui = m_hd = m_b48 = mirr = b_guan=false;
    SolveNd();SHU = 0;
    is11 = is12 = m_game.endless = false;
    if(gq==MAXGQS+15)
    {
        arc=true;
        QString str=ui->dfnz->text();
        char zf[100]={0};
        for(int i=0;i<str.length();i++)zf[i]=str[i].toLatin1();
        freopen(zf,"r",stdin);
        scanf("%d",&arc_cnt);
        ARC sz[10000];
        for(int i=0;i<arc_cnt;i++)
            scanf("%d%d%d",&sz[i].a,&sz[i].b,&sz[i].c);
        sort(sz,sz+arc_cnt);
        for(int i=0;i<arc_cnt;i++)
        {
            arc_tm[i]=sz[i].a;
            arc_wz[i]=sz[i].b;
            arc_ty[i]=sz[i].c;
            if(arc_wz[i]<0)arc_wz[i]=0;
            if(arc_wz[i]>=MN)arc_wz[i]=MN-1;
        }
        fclose(stdin);
    }
    if (gq == MAXGQS + 6) //我是僵尸
    {
        ui->prog->setRange (0, 1);
        ui->prog->setValue (1);
        imjs = chui = true;
        XUAN = MXUAN;
        m_ztm = 0;
        ND = JSH = 0;
        if (plants[0].life < 80)
            plants[0].life = 80;
        else
            plants[0].life = int (80 * pow (plants[0].life / 80.0, 0.7 / 7) + 0.5);
        return 0;
    }
    if(gq==MAXGQS+12)//砸罐子
    {
        ui->prog->setRange (0, 1);
        ui->prog->setValue (1);
        imjs = chui = false;
        XUAN = MXUAN;
        m_ztm = 0;
        ND = JSH = 0;
        b_guan=true;
        return 0;
    }
    int lx = (gq == 2048 ? 0 : (gq - 1) / GQS); //类型
    if (gq == MAXGQS + 3 || gq == MAXGQS + 5 || gq == MAXGQS + 9) //WSAD类,降低难度
    {
        zmb_p[13] = 1;zmb_p[14] = 0;
        plants[23].mush = plants[32].mush = plants[40].mush=false;
        zmb_p[10] -= 1;zmb_p[11] -= 2;zmb_p[12] -= 1;
        zmb_p[15] = 3 - m_ea;zmb_p[16] = 1;
        if (gq == MAXGQS + 9)
        {
            zmb_p[8] = zmb_p[10] = zmb_p[13] = zmb_p[14] = zmb_p[15] = 0, zmb_p[12] -= 1;
            zmb_p[3]-=1;zmb_p[5]-=2;
        }
    }
    m_game.endless = (gq == MAXGQS + 4);
    b_ycl = (gq == MAXGQS + 11||gq == MAXGQS + 13);
    if (lx == 6)
        lx = 0; //特色关卡
    if(lx==7)lx=(gq == MAXGQS + 11?4:0);
    if (lx == 5) //极限模式
    {
        for (int s = 10; s <= 12; s++)
            zmb_p[s] += 1;
        zmb_p[18] += 1;
        for (int s = 0; s <= 21; s++) {
            if (s != 3 && s != 5 && s != 8 && s != 13)
                cd_spd[s] *= 0.7;
        }
        cd_spd[3] *= 0.8;cd_spd[5] *= 0.8;
        cd_spd[8] *= 0.8;cd_spd[13] *= 0.8;
        for (int s = 1; s < MAXSHU; s++)
            plants[s].cost += 10;
        for (int s = 1; s < MAXJSH; s++)
            zombies[s].life += 4;
    }
    plants[18].cost=0;
    if(b_ycl)
        zmb_p[8]-=2,zmb_p[10]-=2,zmb_p[11]-=1,zmb_p[12]-=1;
    if(m_ai)zmb_p[17]=0;
    if(gq==MAXGQS+1)zmb_p[17]=0,zmb_p[8]-=2,zmb_p[10]-=2;
    for (int n = 1; n < MAXJSH; n++) //求概率前缀和
    {
        if (zmb_p[n] < 0)
            zmb_p[n] = 0;
        //m_p[n] += m_p[n - 1];
    }
    int gq2 = gq;
    gq = (gq - 1) % GQS + 1;
    if (gq2 == MAXGQS + 3 || gq2 == MAXGQS + 4 || gq2 == 2048 || gq2 == MAXGQS + 7 || gq2==MAXGQS+11 || gq2==MAXGQS+10)gq = 10;
    if (gq2 == MAXGQS + 5 ||gq2 == MAXGQS + 9)gq = 9;
    if (gq2 == MAXGQS + 8)gq=8;
    if (gq2 == MAXGQS + 14)gq=11;
    //特色关卡的难度
    if (gq2 == MAXGQS + 8)mirr = true; //镜面
    b_zhu = (gq2 == MAXGQS + 10);
    if(b_zhu)plants[38].cost=99999;
    double mr = (lx == 0 ? 1.0 : 3.0);
    double jad = (MAXJSH - mr) / (MANG - 1.0);
    JSH = int (mr) + int (jad * (gq - 1) + 0.5);
    if (gq2 == MAXGQS + 9)JSH = MAXJSH;
    SHU = plt_cnt[gq2 - 1];
    int mj=MAXJSH-2;
    if(gq2>=59)mj+=1;
    if(gq2>=60)mj+=1;
    if (JSH > mj)JSH = mj;
    if (SHU > MAXSHU)SHU = MAXSHU;
    MakeBo(sho,lx,gq,gq2);
    int hnd=1;
    for (int n = 0; n < ND; n++) {
        if (n > 10)
            m_time[n] = m_time[n] * SI / 110; //僵尸双倍
        if (m_jg[n] % m_time[n] == 0) //防止生成变少
            m_jg[n] += 500;
    }
    for(int n=1;n<ND-1;n++)
    {
        if (sho && !m_game.endless) {
            if ((m_gq % 10 == 0 || m_gq == MAXGQS + 3 || m_game.endless) && r_gq != MAXGQS + 5)
                hnd += 1 + (n % 2 == 0);
            else
                hnd += 1 + (n % 4 == 0);
        }
        else {
            if ((m_gq % 10 == 0 || m_gq == MAXGQS + 3 || m_game.endless) && r_gq != MAXGQS + 5)
                hnd += 1;
            else
                hnd += (n % 3 != 0);
        }
    }
    if(JSH>hnd)JSH=hnd;
    int ms = -1; //总时间
    for (int n = 0; n < ND - 1; n++)
        ms += int (m_jg[n] / m_time[n]);
    m_time[ND - 1] = 3000, m_jg[ND - 1] = 100000000;
    XUAN = 9;//卡槽数目
    if (gq2 >= 9 || lx != 0)XUAN = 10;
    if (gq2==MAXGQS || gq2 == MAXGQS + 4 || is12 || b_ycl ||b_zhu||gq2 == MAXGQS + 14)XUAN = 11;
    if (gq2 == MAXGQS + 7)
        XUAN = 0, chui = true, y_sum = 0;
    if (gq2 == MAXGQS + 1) {
        SHU = 0;
        XUAN = 11;
        JSH = MAXJSH;
        is11 = true;
        plants[32].mush = plants[23].mush = false;
        ui->prog->setRange (0, MN * (SI <= 55 ? 3000 : 1000));
        return 0;
    }
    else if (gq2 == MAXGQS + 2) {
        is11 = is12 = true;
        JSH = MAXJSH;
        SHU = MAXSHU;
        ui->prog->setRange (0, MN * (SI <= 55 ? 3000 : 1000));
    }
    else if (gq2 == MAXGQS + 3 || gq2 == MAXGQS + 5 || gq2 == MAXGQS + 9) {
        XUAN = 1;
        m_xuan[0] = 38;
        ui->prog->setRange (0, ms);
    }
    else if (gq2 == 2048) {
        SHU = MAXSHU;
        XUAN = 8;
        int xu[8] = {11, 3, 5, 7, 8, 10, 25, 18};
        for (int s = 0; s < 8; s++)
            m_xuan[s] = xu[s];
        ui->prog->setRange (0, ms);
    }
    else
        ui->prog->setRange (0, ms);
    if(r_gq==MAXGQS+13)JSH=MAXJSH;
    else if (!is12) {
        int tim = 0;
        for (int i = 0; i < ND - 1; i++)
            tim += m_jg[i];
        m_ztm = tim;
        zom_cnt = ms;
        QMessageBox::information (this, tr ("提示"), QString::asprintf ("游戏时间约为%.2lf分钟，约生成僵尸%d个。", (tim / 60000.0) / ui->speed->text ().toDouble (), (mirr ? ms * 2 : ms)));
    }
    if (SHU <= XUAN) {
        for (int n = 0; n < XUAN; n++)
            m_xuan[n] = -1;
        for (int n = 0; n < SHU; n++)
            m_xuan[n] = m_shun[n];
    }
    else if (m_ai) {
        int xu[12] = {0, 10, 7, 8, 6, 41, 3, 5, 12, 22, 25};
        for (int i = 0; i < 11; i++)
            m_xuan[i] = xu[i];
    }
    else if (XUAN > 1 && !m_b48) //选择植物
    {
        Choose *ch = new Choose (this);
#ifdef Q_OS_ANDROID
        QFont f ("", floor (8 * m_sf), false);
        ch->setFont (f);
#endif
        ch->SHU = SHU;
        ch->XUAN = XUAN;
        ch->JSH = JSH;
        QString bt[6] = {"普通", "迷雾", "黑夜", "黑夜+迷雾", "水池", "极限"};
        QString ts[20]={"","僵王","","无尽（水池）","","","","双向僵尸","","柱子","预处理（水池）","","我是植物","WSAD"};
        if (r_gq>MAXGQS)
            ch->setWindowTitle ("选择植物："+ts[r_gq-MAXGQS-1]);
        else
            ch->setWindowTitle ("选择植物：" + bt[lx]);
        for (int i = 0; i < SHU; i++) {
            ch->yg[i] = plants[m_shun[i]].cost;
            ch->ico[i].load (QString::asprintf ("://icons/%d.png", plants[m_shun[i]].id));
        }
        for (int i = 0; i < JSH; i++)
            ch->icj[i].load (QString::asprintf ("://icons/%d.png", zombies[i].id));
        ch->setWindowModality (Qt::ApplicationModal);
        ch->Init ();
        ch->show ();
        if (!ch->exec ())
            throw (1); //未选择
        for (int i = 0; i < XUAN; i++)
            m_xuan[i] = m_shun[ch->xuan[i]];
        m_hbzw = false;
        for (int n = 0; n < XUAN; n++) {
            if (plants[m_xuan[n]].freeze)
                m_hbzw = true;
        }
    }
    if (lx == 2 || lx == 3) //黑夜,降低阳光速率
        plants[0].time *= 1.5, plants[12].time *= 1.5;
    if (m_gq == 30 || m_gq == 62 || m_gq == 64)
        m_gq = 60;
    return lx;
}

void MainWindow::GameOver () {
    /*QString str;
    for(int i=0;i<MAXJSH;i++)
        str+=QString::asprintf("%d\t%d\t%.3lf\n",zmb_sum[i],zmb_p[i],double(zmb_sum[i])/zmb_p[i]);
    QMessageBox::information(this,"",str);*/
    timer.stop ();
    EnableButton();
    if (m_game.started)
        m_game.KillAll ();
    SHU = JSH = ND = tmr_cnt = 0;
    m_game.started = false;
    Init ();
}

void MainWindow::MakeGuan()//砸罐
{
    Plant zw;plants[37].tag = 4;
    zw.Create(QColor(0,0,0),0,1e8,1e8,0,80,0,0,165,0,-1);//罐子
    int zs=(DOU?168:48),gj[10][20],xs=(DOU?14:7);
    int wx[200],wy[200],ws=0;bool gre[10][20];
    while(1)
    {
        int cn=0;ws=0;
        for(int i=0;i<MN;i++)
        {
            for(int j=0;j<=xs;j++)
                gj[i][j]=-1,gre[i][j]=0;
        }
        int ps=zs/(2.2+m_n*0.4)+0.1;
        if(m_n==0)ps=zs/2.4+0.1;
        else if(m_n==1)ps=zs/2.6+0.1;
        for(int i=0;i<ps;i++)
        {
            int kx[25]={3,4,5,35,6,7,8,9,11,14,16,23,25,26,29,32,37,41,15};
            plants[23].mush=plants[32].mush=false;
            int zz=kx[i%19];
            while(1)
            {
                int y=rand()%MN,x=rand()%(xs+1);
                if(gj[y][x]<0)
                {
                    gj[y][x]=zz+1;
                    if(cn<(DOU?6:3))gre[y][x]=1,cn+=1;
                    break;
                }
            }
        }
        pair<int,int> jw[200];int ss=0;
        for(int i=0;i<MN;i++)
        {
            for(int j=0;j<=xs;j++)
            {
                if(gj[i][j]==-1)
                    jw[ss++]=make_pair(i,j);
            }
        }
        shuffle(jw,jw+ss,std::mt19937(std::random_device()()));
        for(int i=0;i<ss;i++)
        {
            int t=i%MAXJSH;
            if(t==17)t+=1;
            gj[jw[i].first][jw[i].second]=-t-1;
        }
        for(int i=0;i<MN;i++)
            for(int j=1;j<MM;j++)
                if(!keep[j][i])wx[ws]=j,wy[ws]=i,ws+=1;
        bool err=0;
        for(int i=0,s=0;i<MN;i++)
            for(int j=0;j<=xs;j++,s++)
                if(wx[s]<=3&&(gj[i][j]==-12||gj[i][j]==-13))
                    err=true;
        if(!err)break;
    }
    for(int i=0;i<MN;i++)
        for(int j=0;j<MM;j++)
            keep[j][i]=0;
    for(int i=0,s=0;i<MN;i++)
    {
        for(int j=0;j<=xs;j++,s++)
        {
            int x=wx[s],y=wy[s];
            zw.x=x*SI;zw.y=y;zw.attack=gj[i][j];
            m_game.DestroyZw(x*SI,y);m_game.m_ice[x][y]=-1e8;
            if(gre[i][j])
                zw.move_spd=-1;
            m_game.m_dc[x][y]=0;m_game.NewZw(zw);
            zw.move_spd=0;
        }
        m_game.car[i]=false;
    }
    m_game.m_yg = 9999;wait=0;
}

void MainWindow::MakeImjs()
{
    bool sho = ui->Short->isChecked ();//是否随机
    plants[37].tag = 4;
    m_game.m_yg = 1000000;
    isstop = false;
    plants[23].mush = plants[32].mush = false;
    for (int i = 0; i < MN; i++) {
        for (int j = 0; j < MN; j++) {
            for (int s = 0; s < MAXSHU; s++)
                plants[s].nxt_tm = rand () % (plants[s].time / 2 + 1) + plants[s].time / 2; //随机开始时间
            int r;
            if (i == 0) {//最左面生成攻击类植物
                int gj[8] = {1, 4, 6, 9, 11, 26, 37, 41};
                r = gj[sho ? rand () % 8 : j % 8];
            }
            else {
                if (sho)//随机
                    r = rand () % MAXSHU;
                else
                    r = ((i + j) * (i * j + 1)) % MAXSHU ;
                if (r == 13 || r == 3 || r == 5 || r == 12 || r == 16 || r == 15 || r == 21 || r == 24 || r == 27 || r == 28 || r == 29 || r == 30 || r == 31 || r == 33 || plants[r].mush ||r==38||r==42) {
                    if ((sho ? rand () % 5 : (i + j) % 5) == 0)
                        r = 0; //增大向日葵概率
                    else {
                        r = (i + 1) % (j + 1);
                        r = r * r * (i * MN + j) % MAXSHU ;
                        if (sho)
                            r = rand () % MAXSHU ;
                        if (r == 13 || r == 3 || r == 5 || r == 12 || r == 16 || r == 15 || r == 21 || r == 24 || r == 27 || r == 28 || r == 29 || r == 30 || r == 31 || r == 33 || plants[r].mush||r==38||r==42)
                            r = 0;
                    }
                }
            }
            plants[r].x = i * SI;
            plants[r].y = j;
            m_game.NewZw (plants[r]);
        }
    }
    m_game.m_yg = 200;
}

void MainWindow::StartGame (int lx) {
    select = -1;
    f_shu = z_fs = 0;
    m_game.m_wnd = this;
    m_n = 0;b_fast=false;
    m_nd = (is11 ||b_ycl? JSH - 1 : 0);
    SetTimer (1000, lx == 5 ? 38 : 45, NULL);//僵尸移动，恢复
    SetTimer (1001, 20, NULL);//子弹移动
    if (!imjs&&!b_ycl&&!b_guan)
        SetTimer (1002, arc?arc_tm[0]:(is11 ? 6000 * pow (SI / 110.0, 0.9) : m_time[0]), NULL);//第一个僵尸
    if ((lx == 0 || lx == 1 || lx == 4 || lx == 5) && !imjs && !b_ycl&&!b_guan)
        SetTimer (1003, (m_b48 ? 10000 : 6000), NULL);//阳光
    if (!imjs&&!b_ycl&&!b_guan&&!arc)
        SetTimer (1004, is11 ? 110000 : m_jg[0], NULL);//第一波
    if (m_ai)
        SetTimer (1008, 400, NULL);//自动
    if (is11) //BOSS
    {
        SetTimer (1005, DOU ? 1500 : 2500, NULL);//生成
        SetTimer (1007, 100000, NULL);//踩
    }
    SetTimer (1009, 25, NULL);
    if ((b_hui = ui->hui->isChecked ())) //生成回放
        SetTimer (1011, 100, NULL);
    for (int n = 0; n < MAXSHU; n++)
        cd[n] = (n==0||n==38||b_guan?800.0:0);
    m_game.CreateGame (lx);
    if (is11) {//BOSS关卡
        for (int n = 0; n < MN; n++)
            m_jwbs[n] = (DOU ? 3000 : 1000);
        if (is12)
            m_game.m_yg = (SI <= 55 ? 4000 : 1500);
        else {
            ui->buy->setVisible (0);
            m_game.m_yg = 9999;
        }
    }
    if (m_gq == MAXGQS + 3)
        ui->buy->setVisible (0);
    for (int n = 0; n < MN; n++)
        m_lstB[n] = -99999999;
    for (int n = 0; n < MN; n++)
        m_lstC[n] = -99999999;
    for (int n = 0; n < MN; n++)
        m_lstD[n] = -99999999;
    for (int n = 0; n < MN; n++)
        m_lstJ[n] = -99999999;
    for (int n = 0; n < MN; n++)
        m_lstT[n] = m_lstZ[n]=-99999999;//清除僵尸历史记录
    jd = tm = 0;
    beans = 3;
    if (m_gq == MAXGQS + 3 || m_gq == MAXGQS + 5 || m_gq == MAXGQS + 9) {//WSAD
        int zx = 0, zy = 0;
        m_game.m_yg = 100000;
        if (m_gq == MAXGQS + 3) {//63
            plants[37].tag = 4;
            for (int i = 0; i < MAXSHU; i++) {
                for (int s = 0; s < wsad[i]; s++) {
                    plants[i].x = zx;
                    plants[i].y = zy;
                    m_game.NewZw (plants[i]);
                    zy += 1;
                    if (zy >= MN)
                        zx += SI, zy = 0;
                }
            }
        }
        else if (m_gq == MAXGQS + 9) {//69
            plants[37].tag = 4;
            for (int i = 0; i < MAXSHU; i++) {
                for (int s = 0; s < wsad2[i]; s++) {
                    plants[i].x = zx;
                    plants[i].y = zy;
                    m_game.NewZw (plants[i]);
                    zy += 1;
                    if (zy >= MN)
                        zx += SI, zy = 0;
                }
            }
        }
        else { //完全图生成器
            for (int s = 0; s < (9 + m_ea - m_hd) * 110 / SI; s++) {
                plants[33].x = zx;
                plants[33].y = zy;
                m_game.NewZw (plants[33]);
                zy += 1;
                if (zy >= MN)
                    zx += SI, zy = 0;
            }
            for (int s = 0; s < 330 / SI; s++) {
                plants[10].x = zx;
                plants[10].y = zy;
                m_game.NewZw (plants[10]);
                zy += 1;
                if (zy >= MN)
                    zx += SI, zy = 0;
            }
            plants[13].x = zx;
            plants[13].y = zy;
            m_game.NewZw (plants[13]);
            zy += 1;
            if (zy >= MN)
                zx += SI, zy = 0;
            plants[27].x = zx;
            plants[27].y = zy;
            m_game.NewZw (plants[27]);
        }
        m_gq = MAXGQS + 3;
    }
    if (m_b48)
        m_game.m_yg = 500;
    bool sho = ui->Short->isChecked ();//是否随机等
    if (imjs) MakeImjs();
    if (m_game.endless && sho) //预设
    {
        m_game.m_yg = 1000000000;
        for (int i = 0; i < MM; i++) {
            for (int j = 0; j < MN; j++) {
                if (m_game.m_keng[i][j] == 2)
                    m_game.m_keng[i][j] = 3;
            }
        }
        for (int i = 0; i < MN; i++) {
            plants[7].x = 660;
            plants[7].y = i;
            m_game.NewZw (plants[7]);
            m_game.m_ng[6 * 110 / SI][i] = 500;
            m_game.m_dc[6 * 110 / SI + 1][i] = 5;
            plants[12].x = 0;
            plants[12].y = i;
            m_game.NewZw (plants[12]);
            plants[11].x = SI;
            plants[11].y = i;
            m_game.NewZw (plants[11]);
        }
        m_game.m_yg = 1000;
    }
    if(r_gq==MAXGQS+13)//我是植物
    {
        m_game.freeze_all=true;
        int wz[MMN],sx[MAXJSH];
        for(int i=0;i<MAXJSH;i++)sx[i]=i;
        for(int i=0;i<MN;i++)wz[i]=(MM-1)*SI;
        shuffle(sx,sx+MAXJSH,std::mt19937(rand()));
        for(int i=0;i<MAXJSH;i++)
        {
            int w=i%MN,z=sx[i];
            if(z==14||z==15)z=3;
            zombies[z].x=wz[w];zombies[z].y=w;
            wz[w]-=SI/2;
            m_game.NewJs(zombies[z]);
        }
        for(int i=0;i<MN;i++)m_game.car[i]=false;
    }
    if (ui->creative->isChecked ()) {
        for (int i = 0; i < MAXSHU; i++)
            cd_spd[i] = 800;
        m_game.m_yg = 100000000;
        plants[37].tag = 4;
    }
    if(b_ycl)
    {
        for(int i=0;i<MAXSHU;i++)
        {
            if(i!=38)
                cd_spd[i]+=800;
        }
        if(r_gq==MAXGQS+13)
            m_game.m_yg=5000,z_fs=2;
        else
            m_game.m_yg=12000*91/SI,z_fs=910/SI-1;
        ui->huisu->setText("进攻");
    }
    else ui->huisu->setText("回溯");
    if(b_zhu)
    {
        for(int i=0;i<MAXSHU;i++)
            cd_spd[i]/=2.5;
        m_game.m_yg=1e9;
    }
    if(b_guan)
    {
        for(int i=0;i<MN;i++)keep[1][i]=keep[2][i]=1;
        MakeGuan();
    }
    gl->update ();
    gx->update ();
    ui->a_swi->setEnabled((m_gq==MAXGQS||m_game.endless||m_gq==MAXGQS+14)&& !m_ai);
}
void MainWindow::SetTimer (int id, int jg, int *nul) {
    double sd = ui->speed->text ().toDouble ();
    if (id == 1001 && sd < 1)//防止速度太慢掉帧
        sd = 1;
    double tj = jg / sd;
    jg = floor (tj + 1e-10);
    if(!b_fast)v_tm=tim.elapsed ();
    tmr[tmr_cnt++] = MyTimer (id, v_tm + jg, jg, tj - jg);
    if (!isstop)
        ResetTimer ();
}
void MainWindow::NewTimer (int id, int jg, int ne) //添加临时计时器
{
    double tj = jg / ui->speed->text ().toDouble ();
    jg = floor (tj + 1e-10);
    if(!b_fast)v_tm=tim.elapsed ();
    tmr[tmr_cnt++] = MyTimer (id, v_tm + ne, jg, tj - jg);
    ResetTimer ();
}
void MainWindow::KillTimer (int id) {
    int z = -1;
    for (int i = 0; i < tmr_cnt; i++) {
        if (tmr[i].id == id) {
            z = i;
            break;
        }
    }
    if (z == -1)
        return;
    tmr_cnt -= 1;
    if (z < tmr_cnt)
        tmr[z] = tmr[tmr_cnt];
    ResetTimer ();
}
void MainWindow::Save (QDataStream &ar) {
    for (int i = 0; i < MAXSHU; i++) {
        plants[i].output (ar);
        ar << cd_spd[i] << cd[i];
    }
    for (int i = 0; i < MAXJSH; i++) {
        zombies[i].output (ar);
        ar << zmb_p[i] << j_yg[i];
    }
    ar << MN << MM << SI << XUAN << TM;
    m_game.output (ar);
    ar << tmr_cnt;
    for (int i = 0; i < tmr_cnt; i++)
        tmr[i].output (ar);
    ar << ND << m_nd << m_n << SHU << JSH << jd << tm << zom_cnt << m_ztm << imjs << chui << mirr << f_shu << z_fs<<b_ycl<<b_fast<<l48<<b_guan<<sun_dou;
    for (int i = 0; i < ND; i++)
        ar << m_time[i] << m_jg[i] <<isdb[i];
    ar << select << sele_x << sele_y << beans;
    for (int i = 0; i < XUAN; i++)
        ar << m_xuan[i];
    for (int i = 0; i < MN; i++)
        ar << m_jwbs[i];
    ar << is11 << is12 << m_hbzw << m_gq << m_ai << r_gq << m_ea << m_hd << m_tui << m_b48;
    for (int i = 0; i < MN; i++)
        ar << m_lstJ[i] << m_lstC[i] << m_lstD[i] << m_lstT[i] << m_lstB[i]<<m_lstZ[i];
    ar << ui->speed->text () << ui->Short->isChecked () << ui->creative->isChecked ();
    ar <<sun_doued<<dis_sum<<stop_cnt;
    for(int i=0;i<MAXJSH;i++)ar<<zmb_sum[i];
    for(int i=0;i<MAXSHU;i++)ar<<plt_sum[i];
    for(int i=0;i<MM;i++)for(int j=0;j<MN;j++)ar<<keep[i][j];
    ar<<wait;
}
void MainWindow::Load (QDataStream &ar) {
    for (int i = 0; i < MAXSHU; i++) {
        plants[i].input (ar);
        ar >> cd_spd[i] >> cd[i];
    }
    for (int i = 0; i < MAXJSH; i++) {
        zombies[i].input (ar);
        ar >> zmb_p[i] >> j_yg[i];
    }
    ar >> MN >> MM >> SI >> XUAN >> TM;
    m_game.input (ar);
    ar >> tmr_cnt;
    for (int i = 0; i < tmr_cnt; i++)
        tmr[i].input (ar);
    ar >> ND >> m_nd >> m_n >> SHU >> JSH >> jd >> tm >> zom_cnt >> m_ztm >> imjs >> chui >> mirr >> f_shu >> z_fs>>b_ycl>>b_fast>>l48>>b_guan>>sun_dou;
    if(b_ycl)
        ui->huisu->setText("进攻");
    else
        ui->huisu->setText("回溯");
    for (int i = 0; i < ND; i++)
        ar >> m_time[i] >> m_jg[i]>>isdb[i];
    ar >> select >> sele_x >> sele_y >> beans;
    for (int i = 0; i < XUAN; i++)
        ar >> m_xuan[i];
    for (int i = 0; i < MN; i++)
        ar >> m_jwbs[i];
    ar >> is11 >> is12 >> m_hbzw >> m_gq >> m_ai >> r_gq >> m_ea >> m_hd >> m_tui >> m_b48;
    for (int i = 0; i < MN; i++)
        ar >> m_lstJ[i] >> m_lstC[i] >> m_lstD[i] >> m_lstT[i] >> m_lstB[i]>>m_lstZ[i];
    QString sd;
    ar >> sd;
    ui->speed->setValue (sd.toDouble ());
    if (m_ea == 4)
        ui->xin->setChecked (1);
    else if (m_ea == 3)
        ui->water->setChecked (1);
    else if (m_ea == 2)
        ui->easy->setChecked (1);
    else if (m_tui)
        ui->tui->setChecked (1);
    else if (m_hd)
        ui->hard->setChecked (1);
    else
        ui->normal->setChecked (1);
    bool sho;
    ar >> sho;
    ui->Short->setChecked (sho);
    ar >> sho;
    ui->creative->setChecked (sho);
    ar >>sun_doued>>dis_sum>>stop_cnt;
    for(int i=0;i<MAXJSH;i++)ar>>zmb_sum[i];
    for(int i=0;i<MAXSHU;i++)ar>>plt_sum[i];
    for(int i=0;i<MM;i++)for(int j=0;j<MN;j++)ar>>keep[i][j];
    ar>>wait;
}
void MainWindow::ResetTimer () //处理计时器
{
    if (isstop)
        return;
    timer.stop ();
    int nw = (b_fast?v_tm:tim.elapsed ()), mi = 1e9, wz = -1;
    for (int i = 0; i < tmr_cnt; i++) {
        if (tmr[i].nxt < mi) {
            mi = tmr[i].nxt;
            wz = tmr[i].id;
        }
    }
    if (wz == -1)
        return;
    int t = mi - nw;
    if (t < 0)
        t = 0;
    nxt_tmr = wz;
    if(!b_fast)
        timer.start (t);
}

void MainWindow::left2048 () {
    if (TM - l48 < 30)//不可用
        return;
    l48 = TM;
    Plant lx[MMM][MMN];
    int dy[MAXSHU];
    for (int i = 0; i < MAXSHU; i++)
        dy[plants[i].type] = i;
    for (int i = 0; i < MN; i++) {//获取植物信息
        for (int j = 0; j < MN; j++) {
            int z = m_game.GetZwShu (j * SI, i);
            if (z == -1)
                lx[j][i].type = -1;
            else
                lx[j][i] = m_game.plants[z];
        }
    }
    for (int i = 0; i < m_game.plt_cnt; i++) {
        if (m_game.plants[i].x / SI < MN) {
            int x = m_game.plants[i].x / SI, y = m_game.plants[i].y;
            lx[x][y].nxt_tm = m_game.DestroyZw (i);//记录（距离下次）时间
            i -= 1;
            if (lx[x][y].time == 100)//取消大招
                lx[x][y].time = plants[dy[lx[x][y].type]].time;
        }
    }
    for (int i = 0; i < MN; i++) {
        Plant st[MMM];
        int tp = 0;
        bool ko = false, bk = false;
        for (int j = 0; j < MN; j++) {
            Plant z = lx[j][i];
            lx[j][i].type = -1;
            if (z.type == -1)
                ko = true;
            else if (ko)
                bk = true;
            while (z.type != -1) { //压栈
                if (tp == 0 || z.type != st[tp - 1].type || n_2048[z.type] <= 0) {
                    st[tp++] = z;
                    z.type = -1;
                }
                else {
                    int t = n_2048[st[--tp].type];
                    if (n_2048[t] == -1) {//最终
                        m_game.m_yg += 1500;
                        if (beans < 5)
                            beans += 1;
                    }
                    z = plants[dy[t]];//新的
                }
            }
        }
        if (tp < MN && rand () % (2 * GL48) == 0 && (tp == 0 || bk)) {//随机生成
            if (tp == 0)
                st[tp++] = plants[1];
            else {
                Plant t = st[tp - 1];
                st[tp++] = (t.type == 0 ? plants[6] : plants[1]);
            }
        }
        for (int j = 0; j < tp; j++)
            lx[j][i] = st[j];
    }
    for (int i = 0; i < MN; i++) {//恢复
        for (int j = 0; j < MN; j++) {
            Plant z = lx[j][i];
            if (z.type == -1)
                continue;
            m_game.m_yg += z.cost;
            z.x = j * SI;
            z.y = i;
            m_game.NewZw (z);
        }
    }
    m_game.CalZw ();
    gl->update ();
    gx->update ();
}
void MainWindow::up2048 () { //同上
    if (TM - l48 < 30)
        return;
    l48 = TM;
    Plant lx[MMM][MMN];
    int dy[MAXSHU];
    for (int i = 0; i < MAXSHU; i++)
        dy[plants[i].type] = i;
    for (int i = 0; i < MN; i++) {
        for (int j = 0; j < MN; j++) {
            int z = m_game.GetZwShu (j * SI, i);
            if (z == -1)
                lx[j][i].type = -1;
            else
                lx[j][i] = m_game.plants[z];
        }
    }
    for (int i = 0; i < m_game.plt_cnt; i++) {
        if (m_game.plants[i].x / SI < MN) {
            int x = m_game.plants[i].x / SI, y = m_game.plants[i].y;
            lx[x][y].nxt_tm = m_game.DestroyZw (i);
            i -= 1;
            if (lx[x][y].time == 100)
                lx[x][y].time = plants[dy[lx[x][y].type]].time;
        }
    }
    for (int j = 0; j < MN; j++) {
        Plant st[MMN];
        int tp = 0;
        bool ko = false, bk = false;
        for (int i = 0; i < MN; i++) {
            Plant z = lx[j][i];
            lx[j][i].type = -1;
            if (z.type == -1)
                ko = true;
            else if (ko)
                bk = true;
            while (z.type != -1) {
                if (tp == 0 || z.type != st[tp - 1].type || n_2048[z.type] <= 0) {
                    st[tp++] = z;
                    z.type = -1;
                }
                else {
                    int t = n_2048[st[--tp].type];
                    if (n_2048[t] == -1) {
                        m_game.m_yg += 1500;
                        if (beans < 5)
                            beans += 1;
                    }
                    z = plants[dy[t]];
                }
            }
        }
        if (tp < MN && rand () % GL48 == 0 && (tp == 0 || bk)) {
            if (tp == 0)
                st[tp++] = plants[1];
            else {
                Plant t = st[tp - 1];
                st[tp++] = (t.type == 0 ? plants[6] : plants[1]);
            }
        }
        for (int i = 0; i < tp; i++)
            lx[j][i] = st[i];
    }
    for (int i = 0; i < MN; i++) {
        for (int j = 0; j < MN; j++) {
            Plant z = lx[j][i];
            if (z.type == -1)
                continue;
            m_game.m_yg += z.cost;
            z.x = j * SI;
            z.y = i;
            m_game.NewZw (z);
        }
    }
    m_game.CalZw ();
    gl->update ();
    gx->update ();
}
void MainWindow::right2048 () { //同上
    if (TM - l48 < 30)
        return;
    l48 = TM;
    Plant lx[MMM][MMN];
    int dy[MAXSHU];
    for (int i = 0; i < MAXSHU; i++)
        dy[plants[i].type] = i;
    for (int i = 0; i < MN; i++) {
        for (int j = 0; j < MN; j++) {
            int z = m_game.GetZwShu (j * SI, i);
            if (z == -1)
                lx[j][i].type = -1;
            else
                lx[j][i] = m_game.plants[z];
        }
    }
    for (int i = 0; i < m_game.plt_cnt; i++) {
        if (m_game.plants[i].x / SI < MN) {
            int x = m_game.plants[i].x / SI, y = m_game.plants[i].y;
            lx[x][y].nxt_tm = m_game.DestroyZw (i);
            i -= 1;
            if (lx[x][y].time == 100)
                lx[x][y].time = plants[dy[lx[x][y].type]].time;
        }
    }
    for (int i = 0; i < MN; i++) {
        Plant st[MMM];
        int tp = 0;
        bool bk = false, ko = false;
        for (int j = MN - 1; j >= 0; j--) {
            Plant z = lx[j][i];
            lx[j][i].type = -1;
            if (z.type == -1)
                ko = true;
            else if (ko)
                bk = true;
            while (z.type != -1) {
                if (tp == 0 || z.type != st[tp - 1].type || n_2048[z.type] <= 0) {
                    st[tp++] = z;
                    z.type = -1;
                }
                else {
                    int t = n_2048[st[--tp].type];
                    if (n_2048[t] == -1) {
                        m_game.m_yg += 1500;
                        if (beans < 5)
                            beans += 1;
                    }
                    z = plants[dy[t]];
                    bk = true;
                }
            }
        }
        if (tp < MN && rand () % GL48 == 0 && (tp == 0 || bk)) {
            if (tp == 0)
                st[tp++] = plants[1];
            else {
                Plant t = st[tp - 1];
                st[tp++] = (t.type == 0 ? plants[6] : plants[1]);
            }
        }
        for (int j = 0; j < tp; j++)
            lx[MN - 1 - j][i] = st[j];
    }
    for (int i = 0; i < MN; i++) {
        for (int j = 0; j < MN; j++) {
            Plant z = lx[j][i];
            if (z.type == -1)
                continue;
            m_game.m_yg += z.cost;
            z.x = j * SI;
            z.y = i;
            m_game.NewZw (z);
        }
    }
    m_game.CalZw ();
    gl->update ();
    gx->update ();
}
void MainWindow::down2048 () { //同上
    if (TM - l48 < 30)
        return;
    l48 = TM;
    Plant lx[MMM][MMN];
    int dy[MAXSHU];
    for (int i = 0; i < MAXSHU; i++)
        dy[plants[i].type] = i;
    for (int i = 0; i < MN; i++) {
        for (int j = 0; j < MN; j++) {
            int z = m_game.GetZwShu (j * SI, i);
            if (z == -1)
                lx[j][i].type = -1;
            else
                lx[j][i] = m_game.plants[z];
        }
    }
    for (int i = 0; i < m_game.plt_cnt; i++) {
        if (m_game.plants[i].x / SI < MN) {
            int x = m_game.plants[i].x / SI, y = m_game.plants[i].y;
            lx[x][y].nxt_tm = m_game.DestroyZw (i);
            i -= 1;
            if (lx[x][y].time == 100)
                lx[x][y].time = plants[dy[lx[x][y].type]].time;
        }
    }
    for (int j = 0; j < MN; j++) {
        Plant st[MMN];
        int tp = 0;
        bool ko = false, bk = false;
        for (int i = MN - 1; i >= 0; i--) {
            Plant z = lx[j][i];
            lx[j][i].type = -1;
            if (z.type == -1)
                ko = true;
            else if (ko)
                bk = true;
            while (z.type != -1) {
                if (tp == 0 || z.type != st[tp - 1].type || n_2048[z.type] <= 0) {
                    st[tp++] = z;
                    z.type = -1;
                }
                else {
                    int t = n_2048[st[--tp].type];
                    if (n_2048[t] == -1) {
                        m_game.m_yg += 1500;
                        if (beans < 5)
                            beans += 1;
                    }
                    z = plants[dy[t]];
                }
            }
        }
        if (tp < MN && rand () % GL48 == 0 && (tp == 0 || bk)) {
            if (tp == 0)
                st[tp++] = plants[1];
            else {
                Plant t = st[tp - 1];
                st[tp++] = (t.type == 0 ? plants[6] : plants[1]);
            }
        }
        for (int i = 0; i < tp; i++)
            lx[j][MN - 1 - i] = st[i];
    }
    for (int i = 0; i < MN; i++) {
        for (int j = 0; j < MN; j++) {
            Plant z = lx[j][i];
            if (z.type == -1)
                continue;
            m_game.m_yg += z.cost;
            z.x = j * SI;
            z.y = i;
            m_game.NewZw (z);
        }
    }
    m_game.CalZw ();
    gl->update ();
    gx->update ();
}
void MainWindow::WakeUp (int y) { //唤醒
    bool bk = false;
    if(!b_fast)v_tm=tim.elapsed ();
    for (int i = 0; i < tmr_cnt; i++) {
        if (tmr[i].time == 100)
            continue;
        int d = tmr[i].id;
        if (d < 1000 && m_game.plants[d].y == y) {
            int lx = m_game.plants[d].type;
            if (lx == 0 || lx == 4 || lx == 9 || lx == 8 || lx == 10 || lx == 13 || lx == 22 || lx == 26 || lx == 37)
                tmr[i].nxt =v_tm + rand () % (tmr[i].time / 50 + 1), bk = true;//防止同时开始造成卡顿
        }
    }
    if (bk&&!b_fast)
        ResetTimer ();
}
